我如何找到一个Bash脚本位于该脚本内部的目录的路径?
我想用Bash脚本作为另一个应用程序的启动器,我想将工作目录更改为Bash脚本所在的目录,所以我可以在该目录中的文件上运行,如下:
$ ./application
我如何找到一个Bash脚本位于该脚本内部的目录的路径?
我想用Bash脚本作为另一个应用程序的启动器,我想将工作目录更改为Bash脚本所在的目录,所以我可以在该目录中的文件上运行,如下:
$ ./application
当前回答
以下是获取脚本信息的简短方式:
文件和文件:
Script: "/tmp/src dir/test.sh"
Calling folder: "/tmp/src dir/other"
使用这些命令:
echo Script-Dir : `dirname "$(realpath $0)"`
echo Script-Dir : $( cd ${0%/*} && pwd -P )
echo Script-Dir : $(dirname "$(readlink -f "$0")")
echo
echo Script-Name : `basename "$(realpath $0)"`
echo Script-Name : `basename $0`
echo
echo Script-Dir-Relative : `dirname "$BASH_SOURCE"`
echo Script-Dir-Relative : `dirname $0`
echo
echo Calling-Dir : `pwd`
我得到了这个结果:
Script-Dir : /tmp/src dir
Script-Dir : /tmp/src dir
Script-Dir : /tmp/src dir
Script-Name : test.sh
Script-Name : test.sh
Script-Dir-Relative : ..
Script-Dir-Relative : ..
Calling-Dir : /tmp/src dir/other
此分類上一篇: https://pastebin.com/J8KjxrPF
其他回答
如果不是由父母脚本来源,而不是同链接,0美元就足够了:
script_path="$0"
如果源于父母脚本而不是同链接,请使用 $BASH_SOURCE 或 ${BASH_SOURCE[0]}:
script_path="$BASH_SOURCE"
如果是同链接,请使用 $BASH_SOURCE 与 realpath 或 readlink -f 获取真正的文件路径:
script_path="$(realpath "$BASH_SOURCE")"
此外,路径或 readlink -f 返回绝对路径。
要获取脚本的目录,使用 dirname:
script_directory="$(dirname "$script_path")"
笔记
对于 MacOS 而言,请在这里或在这里找到一个替代路径或阅读链接 -f. 要使代码与不为 Bash 的支柱兼容,请使用 ${var-string} 参数扩展。
这种方法的一个好处是,它不涉及Bash本身以外的任何东西,也不会破坏任何底层。
首先,使用模式替代替代不以 / (即相对路径) 以 $ PWD/. 因为我们使用替代替代相匹配的第一个字符为 $ 0,我们也必须添加它回来(${0:0:1} 在替代中)。
现在我们有一个完整的路径到脚本;我们可以通过删除最后的 / 和随后的任何东西(即脚本名称)来获得目录。
#!/bin/bash
BIN=${0/#[!\/]/"$PWD/${0:0:1}"}
DIR=${BIN%/*}
cd "$DIR"
如果您的脚本可以源于而不是执行,您可以将 $0 取代 ${BASH_SOURCE[0]},例如:
BIN=${BASH_SOURCE[0]/#[!\/]/"$PWD/${BASH_SOURCE[0]:0:1}"}
这将为可执行的脚本工作,它更长,但更多。
没有<unk>(除了<unk>)和可以处理“陌生人”名称的形式,如那些有新闻,因为有些人会声称:
IFS= read -rd '' DIR < <([[ $BASH_SOURCE != */* ]] || cd "${BASH_SOURCE%/*}/" >&- && echo -n "$PWD")
在我看来,最合适的解决方案是:
"$( cd "$( echo "${BASH_SOURCE[0]%/*}" )"; pwd )"
使用 dirname、 readlink 和 basename 最终会导致兼容性问题,所以如果可能的话最好避免。
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手册)