这是一个非常微妙的。虽然在 bash 中 ${BASH_SOURCE-$0} 和 $BASH_SOURCE 之间没有显着差异,但在 zsh 中获取 bash 文件时它变得实用。
这里有两个方面:
-
数组BASH_SOURCE 的含义以及它与$0 的关系:这在choosing between $0 and BASH_SOURCE 中有很好的解释。但是,BASH_SOURCE 的值仅在 bash 的上下文中定义。其他 shell 不知道这个数组。
-
参数扩展${var-string}:当浏览bash的man page或者任何与POSIX相关的shell比如sh、ksh甚至zsh时,你可以发现${var-string}解析为string如果变量@987654331 @ 不存在。
现在想象以下脚本:
$ cat src.bash
#!/usr/bin/env bash
echo "$0, ${BASH_SOURCE}, ${BASH_SOURCE-$0}"
$ cat exe.bash
#!/usr/bin/env bash
source ./src.bash
$ cat exe.zsh
#!/usr/bin/env zsh
source ./src.bash
当你直接在 bash 中执行这些脚本时,你会得到以下结果:
$ echo "$0, ${BASH_SOURCE}, ${BASH_SOURCE-$0}"
bash, , bash
$ source src.bash
bash, src.bash, src.bash
$ ./exe.bash
./exe.bash, ./src.bash, ./src.bash
这清楚地表明$BASH_SOURCE 和${BASH_SOURCE-$0} 之间没有显着差异。仅当直接从 bash 终端执行时,BASH_SOURCE 不存在并相应地被替换。
从 zsh 开始,情况就不同了。
$ echo "$0, ${BASH_SOURCE}, ${BASH_SOURCE-$0}"
-zsh, , -zsh
$ source src.bash
src.bash, , src.bash
$ ./exe.zsh
./src.bash, , ./src.bash
尽管 zsh 不知道变量 BASH_SOURCE,但它也稍微改变了 $0 的行为。对于 bash,$0 始终是当前执行脚本的名称,而在 zsh 中,它是当前执行的或源脚本的名称。在上面,您可以清楚地看到$BASH_SOURCE 和${BASH_SOURCE-$0} 之间的区别。后者总是返回当前执行或源文件的值。
总之,可以说${BASH_SOURCE-$0} 是一种简单的获取源文件路径的技巧,与脚本来源的外壳无关(zsh 与 bash)。是否出于这个原因在原始脚本中使用它并不确定,但是脚本的作者可能有类似的想法,或者用于编写可以在 zsh 和 bash 中使用的源文件。