Bash脚本路径解析问题:source其他脚本时dirname $0失效
解决source脚本时
dirname $0路径异常的问题 这个问题我之前也踩过坑,核心原因是**$0在source场景下的行为和你预期的不一致**:当你用cd $path_of_2nd_script && source 2nd_script执行source操作时,被source的脚本是在当前shell进程(也就是主脚本的进程)里运行的,$0指向的始终是启动当前shell的主脚本路径,而不是被source的第二个脚本。这就导致dirname $0拿到的是主脚本的目录,自然会出现异常。
下面给你两种可靠的解决方案:
方案1:直接source绝对路径(推荐)
不用切换目录,直接构造第二个脚本的绝对路径进行source,同时在被source的脚本里用BASH_SOURCE替代$0来获取自身路径。
主脚本示例:
# 如果你知道第二个脚本的绝对路径,直接写 second_script="/full/path/to/your/2nd_script.sh" source "$second_script" # 如果第二个脚本路径是相对主脚本的,先获取主脚本的绝对路径再构造 main_script_dir=$(dirname "${BASH_SOURCE[0]}") # 比如第二个脚本在主脚本的上级目录的scripts文件夹里 second_script="$main_script_dir/../scripts/2nd_script.sh" # 转换成绝对路径避免相对路径问题 second_script=$(realpath "$second_script") source "$second_script"
被source的脚本(2nd_script.sh)示例:
# 获取自身所在的目录(相对路径) script_dir=$(dirname "${BASH_SOURCE[0]}") # 转换成绝对路径(可选,但更稳妥,避免cd带来的路径变化) script_dir=$(realpath "$script_dir") # 之后就可以用$script_dir来引用脚本所在目录的资源了,比如: # source "$script_dir/utils.sh" # cp "$script_dir/config.ini" /tmp/
方案2:保留cd操作,但修改被source脚本的路径获取逻辑
如果因为某些原因必须先cd到第二个脚本的目录再source,那依然要在被source的脚本里用BASH_SOURCE替代$0,因为$0还是指向主脚本。
修改后的被source脚本逻辑和方案1里的完全一样,只需要把dirname $0替换成dirname "${BASH_SOURCE[0]}"即可,这样不管你有没有cd,都能拿到正确的自身路径。
补充说明:关于BASH_SOURCE
BASH_SOURCE是bash提供的特殊数组,其中BASH_SOURCE[0]代表当前正在执行的脚本文件的路径——不管这个脚本是被直接执行还是被source,它都能准确指向脚本自身。这是bash环境下替代$0获取脚本路径的标准做法。
如果你的系统没有realpath命令,可以用readlink -f来替代:
script_dir=$(readlink -f "$(dirname "${BASH_SOURCE[0]}")")
内容的提问来源于stack exchange,提问作者Birbal
相关产品推荐
相关产品推荐

