我如何找到一个Bash脚本位于该脚本内部的目录的路径?
我想用Bash脚本作为另一个应用程序的启动器,我想将工作目录更改为Bash脚本所在的目录,所以我可以在该目录中的文件上运行,如下:
$ ./application
我如何找到一个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 以完整的路径提供,无论它是如何称呼的。
只需确保您在脚本开始时找到此处。
其他回答
此单行在 Cygwin 上工作,即使脚本已被从 Windows 称为 bash -c <script>:
set mydir="$(cygpath "$(dirname "$0")")"
下面是简单而正确的方式:
actual_path=$(readlink -f "${BASH_SOURCE[0]}")
script_dir=$(dirname "$actual_path")
解释:
${BASH_SOURCE[0]} - 完整的路径到脚本. 这个值将是正确的,即使脚本是源,例如源 <(echo 'echo $0') 打印 bash,同时取代它为 ${BASH_SOURCE[0]} 将打印整个路径的脚本。
我想评论上面的答案(我如何从脚本本身中获取Bash脚本的源目录?),但没有足够的声誉来做到这一点。
我在两年前在苹果的文档网站上找到了一个解决方案: https://developer.apple.com/library/archive/documentation/OpenSource/Conceptual/ShellScripting/AdvancedTechniques/AdvancedTechniques.html。
#!/bin/sh
# Get an absolute path for the poem.txt file.
POEM="$PWD/../poem.txt"
# Get an absolute path for the script file.
SCRIPT="$(which $0)"
if [ "x$(echo $SCRIPT | grep '^\/')" = "x" ] ; then
SCRIPT="$PWD/$SCRIPT"
fi
正如代码所表明的那样,一旦您获得脚本的绝对路径,则您可以使用命令命名以获得目录的路径。
最短、最优雅的方式就是:
#!/bin/bash
DIRECTORY=$(cd `dirname $0` && pwd)
echo $DIRECTORY
它会在所有平台上工作,而且非常干净。
更多详细信息可在“该 bash 脚本在哪个目录?”中找到。
还有另一个选项:
SELF=$(SELF=$(dirname "$0") && bash -c "cd \"$SELF\" && pwd")
echo "$SELF"
它在 macOS 上也起作用,确定了频道路径,并且不会改变当前的目录。