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

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

$ ./application

当前回答

如果你的Bash脚本是一个同链接,那么这就是如何做到这一点:

#!/usr/bin/env bash

dirn="$(dirname "$0")"
rl="$(readlink "$0")";
exec_dir="$(dirname $(dirname "$rl"))";
my_path="$dirn/$exec_dir";
X="$(cd $(dirname ${my_path}) && pwd)/$(basename ${my_path})"

X 是包含您的 Bash 脚本的目录(原始文件,而不是同链接)。我向上帝发誓这项工作,这是我唯一知道如何正确地做到这一点。

其他回答

使用阅读链接的组合来编码名称(如果是同链接,则将其返回来源的奖金)并提取目录名称:

script="`readlink -f "${BASH_SOURCE[0]}"`"
dir="`dirname "$script"`"

我用三种不同的处决尝试了追踪。

echo $(实际上是 $_)

. application         # /correct/path/to/dir or /path/to/temporary_dir
bash application      # /path/to/bash
/PATH/TO/application  # /correct/path/to/dir

echo $(相当于 $(相当于 $0))

. application         # failed with `realpath: missing operand`
bash application      # /correct/path/to/dir
/PATH/TO/application  # /correct/path/to/dir

echo $(相当于 $BASH_SOURCE)

$BASH_SOURCE 基本上与 ${BASH_SOURCE[0]} 相同。

. application         # /correct/path/to/dir
bash application      # /correct/path/to/dir
/PATH/TO/application  # /correct/path/to/dir

只有$(实际上是$BASH_SOURCE)似乎是可靠的。

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

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

scriptdir=`dirname "$PRG"`

这在Bash 3.2中工作:

path="$( dirname "$( which "$0" )" )"

如果您在 $PATH 中有 ~/bin 目录,则在此目录中有 A. 它源于 ~/bin/lib/B. 您知道所包含的目录与原始目录相对,在 lib 子目录中,但不是与用户当前目录相对。

以以下方式解决问题(A内部):

source "$( dirname "$( which "$0" )" )/lib/B"

无论用户在哪里,还是他/她如何呼叫脚本,这总是会工作。

这是我唯一能以可靠的方式说的话:

SCRIPT_DIR=$(dirname $(cd "$(dirname "$BASH_SOURCE")"; pwd))