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

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

$ ./application

当前回答

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 以完整的路径提供,无论它是如何称呼的。

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

其他回答

这些其他答案中没有一个为Finder在OS X中启动的Bash脚本工作。

SCRIPT_LOC="`ps -p $$ | sed /PID/d | sed s:.*/Network/:/Network/: |
sed s:.*/Volumes/:/Volumes/:`"

它不太好,但它完成了工作。

pwd 可以用来找到当前工作目录,而 dirname 可以用来找到特定文件的目录(运行命令为 $0,所以 dirname $0 应该给你当前脚本的目录)。

然而,字体名称给出了字体名称的目录部分,这更有可能与当前工作目录无关,如果你的脚本需要因某种原因更改目录,那么字体名称的输出就会变得毫无意义。

我建议如下:

#!/usr/bin/env bash

reldir="$( dirname -- "$0"; )";
cd "$reldir";
directory="$( pwd; )";

echo "Directory is ${directory}";

这样,你就得到一个绝对的,而不是一个相对的目录。

由于脚本将在一个单独的Bash例子中运行,没有必要恢复工作目录后,但如果你想因某种原因改变你的脚本,你可以轻松地将PWD的值分配给一个变量,在你更改目录之前,用于未来的使用。

雖然只是

cd "$( dirname -- "$0"; )";

解决这个问题的具体场景,我发现有绝对的道路到更有用的一般。

$(dirname "$(readlink -f "$BASH_SOURCE")")

此分類上一篇: Mac OS X v10.6.6 (Snow Leopard):

DIR=$(cd "$(dirname "$0")"; pwd)

我会用这样的东西:

# Retrieve the full pathname of the called script
scriptPath=$(which $0)

# Check whether the path is a link or not
if [ -L $scriptPath ]; then

    # It is a link then retrieve the target path and get the directory name
    sourceDir=$(dirname $(readlink -f $scriptPath))

else

    # Otherwise just get the directory name of the script path
    sourceDir=$(dirname $scriptPath)

fi