Bash脚本引用自身目录时如何避免被引用脚本的$DIR变量覆盖?
解决方案
方案1:用函数封装脚本逻辑 + 局部变量隔离(最推荐)
Bash 函数内的 local 变量仅在当前函数作用域生效,不会污染全局命名空间,也不会被其他脚本的同名变量覆盖,同时支持声明局部只读属性。
通用模板如下:
#!/bin/bash # 任意脚本通用开头模板 set -euo pipefail # 整个脚本逻辑封装到主函数内 __main() { # 声明局部目录变量,仅当前函数可用,加-r即可设置只读 local -r DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" &>/dev/null && pwd -P) # 你的脚本逻辑写在这里 echo "当前脚本所在目录:$DIR" # 引用其他脚本也不会覆盖当前的DIR source "$DIR/../prj2/script2.sh" echo "当前脚本的DIR仍然是:$DIR" } # 执行主函数 __main "$@"
所有脚本都采用这个模板开发的话,各自的$DIR完全隔离,不会互相影响,就算被引用的子脚本也使用同样模板也不会发生冲突。
方案2:生成脚本独有的全局变量名
如果不想用函数封装,可以把目录变量和当前脚本绑定,生成唯一的变量名避免冲突:
#!/bin/bash set -euo pipefail # 提取当前脚本名作为变量前缀,把横杠替换为下划线适配变量命名规则 _SCRIPT_PREFIX=$(basename "${BASH_SOURCE[0]}" .sh | tr '-' '_') # 生成唯一的目录变量,设为只读 declare -r "${_SCRIPT_PREFIX}_DIR"=$(cd "$(dirname "${BASH_SOURCE[0]}")" &>/dev/null && pwd -P) # 清理临时前缀变量 unset _SCRIPT_PREFIX # 使用的时候调用对应脚本的变量即可 echo "script1的目录是:${script1_DIR}" source "$script1_DIR/../prj2/script2.sh" echo "script2的目录是:${script2_DIR}"
方案3:临时备份变量(适配存量未改造的脚本)
如果被引用的是已经开发完成的存量脚本无法修改,可以在source前备份自己的DIR变量,引用完成后恢复:
#!/bin/bash DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" &>/dev/null && pwd -P) echo "script1目录:$DIR" # 备份原有值 _OLD_DIR=$DIR # 引用其他脚本 source "$DIR/../prj2/script2.sh" # 恢复原有值 DIR=$_OLD_DIR unset _OLD_DIR echo "恢复后的script1目录:$DIR"
关于readonly属性的适配说明
如果使用方案1的函数局部变量写法,local -r 声明的只读变量仅在当前函数内生效,不同脚本的局部只读变量互不干扰,完美解决了全局readonly变量无法重赋值的问题。
内容的提问来源于stack exchange,提问作者jmtornetta
相关产品推荐
相关产品推荐

