我如何找到一个Bash脚本位于该脚本内部的目录的路径?

我想用Bash脚本作为另一个应用程序的启动器,我想将工作目录更改为Bash脚本所在的目录,所以我可以在该目录中的文件上运行,如下:

$ ./application

当前回答

$_ 值得提到为 $0 的替代品。 如果您正在运行来自 Bash 的脚本,可将接受的答案缩短到:

DIR="$( dirname "$_" )"

请注意,这应该是您的脚本中的第一个声明。

其他回答

我不认为这是像其他人这样容易的。 pwd 不工作,因为当前的目录不一定是与脚本的目录。 $0 不总是有信息。

./script

/usr/bin/script

script

在第一和第三方式 $0 没有完整的路径信息. 在第二和第三, pwd 不工作. 唯一的方式来获得目录的第三方式将是通过路径运行并找到文件与正确的匹配。

做你正在要求的一种方式,就是在 /usr/share 目录中的数据硬编码,并将其引用到其完整的路径。

pushd . > '/dev/null';
SCRIPT_PATH="${BASH_SOURCE[0]:-$0}";

while [ -h "$SCRIPT_PATH" ];
do
    cd "$( dirname -- "$SCRIPT_PATH"; )";
    SCRIPT_PATH="$( readlink -f -- "$SCRIPT_PATH"; )";
done

cd "$( dirname -- "$SCRIPT_PATH"; )" > '/dev/null';
SCRIPT_PATH="$( pwd; )";
popd  > '/dev/null';

它适用于所有版本,包括

当通过多个深度软链接呼叫时,当文件时,当脚本被命令“源”称为. (dot) 操作员时,当 arg $0 从呼叫器修改时,“./script” “/full/path/to/script” “/some/path/../../other/path/script” “./some/folder/script”

否则,如果Bash脚本本身是一个相对的Symlink,你想跟随它并返回链接到脚本的完整路径:

pushd . > '/dev/null';
SCRIPT_PATH="${BASH_SOURCE[0]:-$0}";

while [ -h "$SCRIPT_PATH" ];
do
    cd "$( dirname -- "$SCRIPT_PATH"; )";
    SCRIPT_PATH="$( readlink -f -- "$SCRIPT_PATH"; )";
done

cd "$( dirname -- "$SCRIPT_PATH"; )" > '/dev/null';
SCRIPT_PATH="$( pwd; )";
popd  > '/dev/null';

SCRIPT_PATH 以完整的路径提供,无论它是如何称呼的。

只需确保您在脚本开始时找到此处。

以下是一個符合 POSIX 的單線:

SCRIPT_PATH=`dirname "$0"`; SCRIPT_PATH=`eval "cd \"$SCRIPT_PATH\" && pwd"`

# test
echo $SCRIPT_PATH

我通常将以下列入我的脚本的顶部,这在大多数情况下工作:

[ "$(dirname $0)" = '.' ] && SOURCE_DIR=$(pwd) || SOURCE_DIR=$(dirname $0);
ls -l $0 | grep -q ^l && SOURCE_DIR=$(ls -l $0 | awk '{print $NF}');

第一行根据PWD的值指定源,如果从当前路径运行,或者如果从其他地方呼叫,则命名。

第二行检查路径,以确定它是否是一个同链接,如果是这样,更新 SOURCE_DIR 到链接本身的位置。

可能有更好的解决方案在那里,但这是我成功的最干净的。

$_ 值得提到为 $0 的替代品。 如果您正在运行来自 Bash 的脚本,可将接受的答案缩短到:

DIR="$( dirname "$_" )"

请注意,这应该是您的脚本中的第一个声明。