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

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

$ ./application

当前回答

這是我多年來創造的,用作我的Bash寫作的標題:

## BASE BRAIN - Get where you're from and who you are.
MYPID=$$
ORIGINAL_DIR="$(pwd)" # This is not a hot air balloon ride..
fa="$0" # First Assumption
ta= # Temporary Assumption
wa= # Weighed Assumption
while true; do
    [ "${fa:0:1}" = "/" ] && wa=$0 && break
    [ "${fa:0:2}" = "./" ] && ta="${ORIGINAL_DIR}/${fa:2}" && [ -e "$ta" ] && wa="$ta" && break
    ta="${ORIGINAL_DIR}/${fa}" && [ -e "$ta" ] && wa="$ta" && break
done
SW="$wa"
SWDIR="$(dirname "$wa")"
SWBIN="$(basename "$wa")"
unset ta fa wa
( [ ! -e "$SWDIR/$SWBIN" ] || [ -z "$SW" ] ) && echo "I could not find my way around :( possible bug in the TOP script" && exit 1

此时此刻,您的变量 SW、SWDIR 和 SWBIN 包含您需要的内容。

其他回答

下面是一个命令,在Bash或zsh下工作,以及是否单独执行或源:

[ -n "$ZSH_VERSION" ] && this_dir=$(dirname "${(%):-%x}") \
    || this_dir=$(dirname "${BASH_SOURCE[0]:-$0}")

它是如何工作的

Fallback 替代操作员:

% x=ok
% echo "${x}"
ok

% echo "${x:-fallback}"
ok

% x=
% echo "${x:-fallback}"
fallback

% y=yvalue
% echo "${x:-$y}"
yvalue

此分類上一篇: %x prompt escape code

接下来,我们将引入即时逃避代码,一个 zsh-only 功能. 在 zsh 中, %x 将扩展到文件的路径,但通常只有在进行即时行扩展时。

% cat apath/test.sh
fpath=%x
echo "${(%)fpath}"

% source apath/test.sh
apath/test.sh

% cd apath
% source test.sh
test.sh

% cat test.sh
echo "${(%):-%x}"

% source test.sh
test.sh

请注意,我们通常会把变量名称放在(%)和(%)之间,但我们留下了白色。

我们可能已经使用打印 -P %x 以获得相同的文件路径,有更少的黑客,但在我们的情况下,我们需要将其作为一个论点转到一个字符串,这将需要一个开始一个新的字符串的顶部:

% cat apath/test.sh
dirname "$(print -P %x)"  # $(...) runs a command in a new process
dirname "${(%):-%x}"

% source apath/test.sh
apath
apath

显然,黑客的方式既更有效又更简短。

对于具有 GNU coreutils readlink 的系统(例如,Linux):

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

您不需要使用 BASH_SOURCE 当 $0 包含脚本文件名时。

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

这是一个纯粹的Bash解决方案。

$ cat a.sh
BASENAME=${BASH_SOURCE/*\/}
DIRNAME=${BASH_SOURCE%$BASENAME}.
echo $DIRNAME

$ a.sh
/usr/local/bin/.

$ ./a.sh
./.

$ . a.sh
/usr/local/bin/.

$ /usr/local/bin/a.sh
/usr/local/bin/.

這是Linux的特點,但你可以使用:

SELF=$(readlink /proc/$$/fd/255)