我如何找到一个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 以完整的路径提供,无论它是如何称呼的。
只需确保您在脚本开始时找到此处。
其他回答
这里是JavaScript(即Node.js)的替代方案:
baseDirRelative=$(dirname "$0")
baseDir=$(node -e "console.log(require('path').resolve('$baseDirRelative'))") # Get absolute path using Node.js
echo $baseDir
我通常将以下列入我的脚本的顶部,这在大多数情况下工作:
[ "$(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 到链接本身的位置。
可能有更好的解决方案在那里,但这是我成功的最干净的。
这在Bash 3.2中工作:
path="$( dirname "$( which "$0" )" )"
如果您在 $PATH 中有 ~/bin 目录,则在此目录中有 A. 它源于 ~/bin/lib/B. 您知道所包含的目录与原始目录相对,在 lib 子目录中,但不是与用户当前目录相对。
以以下方式解决问题(A内部):
source "$( dirname "$( which "$0" )" )/lib/B"
无论用户在哪里,还是他/她如何呼叫脚本,这总是会工作。
使用阅读链接的组合来编码名称(如果是同链接,则将其返回来源的奖金)并提取目录名称:
script="`readlink -f "${BASH_SOURCE[0]}"`"
dir="`dirname "$script"`"
简短答案:
"`dirname -- "$0";`"
或(最好是):
"$( dirname -- "$0"; )"