我如何找到一个Bash脚本位于该脚本内部的目录的路径?
我想用Bash脚本作为另一个应用程序的启动器,我想将工作目录更改为Bash脚本所在的目录,所以我可以在该目录中的文件上运行,如下:
$ ./application
我如何找到一个Bash脚本位于该脚本内部的目录的路径?
我想用Bash脚本作为另一个应用程序的启动器,我想将工作目录更改为Bash脚本所在的目录,所以我可以在该目录中的文件上运行,如下:
$ ./application
当前回答
这应该是这样做的:
DIR="$(dirname "$(realpath "$0")")"
这与路线上的交线和空间一起工作。
请参见男人的页面为 dirname 和 realpath。
请添加关于如何支持MacOS的评论,对不起,我可以验证。
其他回答
dirname ${BASH_SOURCE[${#BASH_SOURCE[@]} - 1]}
如果您想跟随同步链接,请使用您上面的路径上的阅读链接,重复或非重复。
#
# Location: test1/test2/test_script.sh
#
echo $0
echo $_
echo ${BASH_SOURCE}
echo ${BASH_SOURCE[${#BASH_SOURCE[@]} - 1]}
cur_file="${BASH_SOURCE[${#BASH_SOURCE[@]} - 1]}"
cur_dir="$(dirname "${cur_file}")"
source "${cur_dir}/func_def.sh"
function test_within_func_inside {
echo ${BASH_SOURCE}
echo ${BASH_SOURCE[${#BASH_SOURCE[@]} - 1]}
}
echo "Testing within function inside"
test_within_func_inside
echo "Testing within function outside"
test_within_func_outside
#
# Location: test1/test2/func_def.sh
#
function test_within_func_outside {
echo ${BASH_SOURCE}
echo ${BASH_SOURCE[${#BASH_SOURCE[@]} - 1]}
}
BASH - 来源
一个序列变量,其成员是源文件名,在 FUNCNAME序列变量中定义了相应的序列函数名称。
功能
这个变量可以使用 BASH_LINENO 和 BASH_SOURCE. FUNCNAME 的每个元素都有相应的元素在 BASH_LINENO 和 BASH_SOURCE 描述呼叫板. 例如, ${FUNCNAME[$i]} 被呼叫从文件 ${BASH_SOURCE[$i+1]} 到线号 ${BASH_LINENO[$i]}。
(源:Bash手册)
我通常将以下列入我的脚本的顶部,这在大多数情况下工作:
[ "$(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脚本是一个同链接,那么这就是如何做到这一点:
#!/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 脚本的目录(原始文件,而不是同链接)。我向上帝发誓这项工作,这是我唯一知道如何正确地做到这一点。
在我看来,最合适的解决方案是:
"$( cd "$( echo "${BASH_SOURCE[0]%/*}" )"; pwd )"
使用 dirname、 readlink 和 basename 最终会导致兼容性问题,所以如果可能的话最好避免。
使用“0”字母:
#!/usr/bin/env bash
echo "The script you are running has basename $( basename -- "$0"; ), dirname $( dirname -- "$0"; )";
echo "The present working directory is $( pwd; )";
使用 pwd 单独不会工作,如果您不从它包含的目录中运行脚本。
[matt@server1 ~]$ pwd
/home/matt
[matt@server1 ~]$ ./test2.sh
The script you are running has basename test2.sh, dirname .
The present working directory is /home/matt
[matt@server1 ~]$ cd /tmp
[matt@server1 tmp]$ ~/test2.sh
The script you are running has basename test2.sh, dirname /home/matt
The present working directory is /tmp