如何用相对路径正确引用Bash脚本?解决跨目录调用报错问题
解决脚本相对路径调用的依赖问题
这个坑我踩过好多次!你遇到的报错核心原因很明确:shell里的相对路径是基于你执行脚本时的当前工作目录,而不是脚本文件本身所在的目录。
举个例子:你在Script C所在的目录执行./C.sh,此时你的工作目录是C的目录。当B.sh里执行source ./A.sh时,shell会去当前工作目录(C的目录)找A.sh,而不是B.sh所在的libs目录,自然就找不到了。
下面给你几个可迁移、不用硬编码绝对路径的解决方案,按推荐度排序:
方案1:让脚本自己获取自身所在目录(最健壮)
在Script B(libs/B.sh)的开头添加一段代码,先拿到脚本本身的绝对路径目录,再用这个目录来调用A.sh:
# 获取当前脚本所在的绝对目录 SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" &> /dev/null && pwd) # 用这个目录来调用同目录下的A.sh source "$SCRIPT_DIR/A.sh"
原理说明:
${BASH_SOURCE[0]}:当前正在执行的脚本文件的路径(不管你从哪里调用它)dirname "${BASH_SOURCE[0]}":提取出脚本所在的目录部分cd ... && pwd:进入这个目录后执行pwd,得到绝对路径(避免相对路径的问题)- 最后用
"$SCRIPT_DIR/A.sh"就能精准定位到同目录下的A.sh,无论你在哪个目录执行C.sh都没问题。
方案2:Bash 4.0+ 简化写法
如果你的环境是Bash 4.0及以上版本,可以用更简洁的字符串替换来获取脚本目录,省去cd和pwd的步骤:
# 直接提取脚本所在目录(Bash 4.0+支持) SCRIPT_DIR="${BASH_SOURCE[0]%/*}" source "$SCRIPT_DIR/A.sh"
这个写法更短,原理是%/*会去掉${BASH_SOURCE[0]}里最后一个/及后面的内容,剩下的就是目录路径。
方案3:在调用方切换目录(不推荐,影响范围大)
你也可以在Script C里先切换到libs目录再调用B.sh,但这种方法可能会影响C.sh里其他依赖相对路径的操作,需要额外处理回退:
# 在Script C中: # 先保存原来的工作目录 ORIGINAL_DIR=$(pwd) # 切换到libs目录(这里用C.sh的目录来拼接libs路径) cd "$(dirname "${BASH_SOURCE[0]}")/libs" # 调用B.sh source ./B.sh # 切回原来的目录 cd "$ORIGINAL_DIR"
这种方法不如前两种灵活,因为如果后续B.sh被其他脚本调用,还是会出问题,所以优先推荐方案1。
总结一下,方案1是最通用、最健壮的,它让每个脚本都能独立处理自己的依赖路径,完全满足你“可迁移、无需永久编辑”的需求——只需要修改一次B.sh,不管把整个目录移到哪里,脚本都能正常运行。
内容的提问来源于stack exchange,提问作者Kirill Rud
相关产品推荐
相关产品推荐

