我如何找到一个Bash脚本位于该脚本内部的目录的路径?
我想用Bash脚本作为另一个应用程序的启动器,我想将工作目录更改为Bash脚本所在的目录,所以我可以在该目录中的文件上运行,如下:
$ ./application
我如何找到一个Bash脚本位于该脚本内部的目录的路径?
我想用Bash脚本作为另一个应用程序的启动器,我想将工作目录更改为Bash脚本所在的目录,所以我可以在该目录中的文件上运行,如下:
$ ./application
当前回答
我认为最简单的答案是原始变量的参数扩展:
#!/usr/bin/env bash
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
echo "opt1; original answer: $DIR"
echo ''
echo "opt2; simple answer : ${BASH_SOURCE[0]%/*}"
它应该产生产量如:
$ /var/tmp/test.sh
opt1; original answer: /var/tmp
opt2; simple answer : /var/tmp
变量/参数扩展 ${BASH_SOURCE[0]%/*}”似乎更容易保持。
其他回答
此单行在 Cygwin 上工作,即使脚本已被从 Windows 称为 bash -c <script>:
set mydir="$(cygpath "$(dirname "$0")")"
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 以完整的路径提供,无论它是如何称呼的。
只需确保您在脚本开始时找到此处。
这在Bash 3.2中工作:
path="$( dirname "$( which "$0" )" )"
如果您在 $PATH 中有 ~/bin 目录,则在此目录中有 A. 它源于 ~/bin/lib/B. 您知道所包含的目录与原始目录相对,在 lib 子目录中,但不是与用户当前目录相对。
以以下方式解决问题(A内部):
source "$( dirname "$( which "$0" )" )/lib/B"
无论用户在哪里,还是他/她如何呼叫脚本,这总是会工作。
$(dirname "$(readlink -f "$BASH_SOURCE")")
这些其他答案中没有一个为Finder在OS X中启动的Bash脚本工作。
SCRIPT_LOC="`ps -p $$ | sed /PID/d | sed s:.*/Network/:/Network/: |
sed s:.*/Volumes/:/Volumes/:`"
它不太好,但它完成了工作。