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

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

$ ./application

当前回答

#!/bin/sh
PRG="$0"

# need this for relative symlinks
while [ -h "$PRG" ] ; do
   PRG=`readlink "$PRG"`
done

scriptdir=`dirname "$PRG"`

其他回答

您可以使用 $BASH_SOURCE:

#!/usr/bin/env bash

scriptdir="$( dirname -- "$BASH_SOURCE"; )";

请注意,您需要使用 #!/bin/bash 而不是 #!/bin/sh 因为它是一个 Bash 扩展。

好吧,如果在路上,字母和字母只是不会切断它,走路是艰难的(如果父母没有出口PATH?!)。

然而,盾牌必须对其脚本有一个开放的手稿,而在Bash手稿是#255。

SELF=`readlink /proc/$$/fd/255`

为我工作。

下面是一个命令,在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

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

這是解決方案 e-satis 和 3bcdnlklvc04a 在他們的答案中指出的輕微改訂:

SCRIPT_DIR=''
pushd "$(dirname "$(readlink -f "$BASH_SOURCE")")" > /dev/null && {
    SCRIPT_DIR="$PWD"
    popd > /dev/null
}

这应该在他们列出的所有情况下仍然有效。

这将防止一个失败的冲动之后的Popd. 感谢控制台。

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

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

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