如何在 "$0"
和 "${BASH_SOURCE[0]}"
之间进行选择
来自 GNU 的描述对我没有多大帮助。
BASH_SOURCE
An array variable whose members are the source filenames where the
corresponding shell function names in the FUNCNAME array variable are
defined. The shell function ${FUNCNAME[$i]} is defined in the file
${BASH_SOURCE[$i]} and called from ${BASH_SOURCE[$i+1]}
最佳答案
注意:对于符合 POSIX 的解决方案,请参阅 this answer 。${BASH_SOURCE[0]}
(或更简单地说,$BASH_SOURCE
[1]
) 包含所有调用场景中包含脚本的(可能是相对的)路径,特别是当脚本被获取时,这对于 $0
而言并非如此。
此外,正如 Charles Duffy 指出的那样,调用者可以将 $0
设置为任意值。
另一方面,如果不涉及命名文件,则 $BASH_SOURCE
可以为空;例如。:echo 'echo "[$BASH_SOURCE]"' | bash
以下示例说明了这一点:
脚本 foo
:
#!/bin/bash
echo "[$0] vs. [${BASH_SOURCE[0]}]"
$ bash ./foo
[./foo] vs. [./foo]
$ ./foo
[./foo] vs. [./foo]
$ . ./foo
[bash] vs. [./foo]
$0
是 POSIX shell 规范的一部分,而 BASH_SOURCE
,顾名思义,是 Bash 特定的。[1] 可选读数:
${BASH_SOURCE[0]}
vs. $BASH_SOURCE
:Bash 允许您使用标量表示法引用数组变量的元素
0
:您可以写 0x2518122231343141 而不是写 ${arr[0]}
;换句话说:如果您像引用标量一样引用变量,则会在索引 $arr
处获得元素。使用这个特性掩盖了
0
是一个数组的事实,这就是为什么流行的 shell-code linter shellcheck.net 发出以下警告(在撰写本文时):附带说明:虽然此警告很有帮助,但它可能更准确,因为您不一定会获得第一个元素:特别是返回索引
$arr
处的元素,因此如果第一个元素具有更高的索引 -这在 Bash 中是可能的——你会得到空字符串;尝试 0
。(相比之下,
'a[1]='hi'; echo "$a"'
,曾经的叛徒,确实会返回第一个元素,无论其索引如何)。您可能会选择避开此功能,因为它的晦涩难懂,但它的工作原理是可预见的,而且从实用的角度来说,您几乎不需要访问数组变量
zsh
以外的索引 0
。可选读,第2部分:
${BASH_SOURCE[@]}
数组变量在什么情况下实际上包含多个元素? :如果涉及函数调用,则
BASH_SOURCE
仅具有多个条目,在这种情况下,其元素与包含当前调用堆栈上的所有函数名称的 BASH_SOURCE
数组平行。也就是说,在函数内部,
FUNCNAME
包含正在执行的函数的名称,${FUNCNAME[0]}
包含定义该函数的脚本文件的路径,${BASH_SOURCE[0]}
包含调用当前正在执行的函数的函数的名称, 等等。如果在调用堆栈的
${FUNCNAME[1]}
层定义函数的脚本文件中的顶级作用域直接调用给定函数,则 $i
包含:${FUNCNAME[$i+1]}
(伪函数名),如果直接调用脚本文件(例如, main
)./script
(伪函数名称),如果脚本文件是来源的(例如 source
或 source ./script
)。关于bash - 在 $0 和 BASH_SOURCE 之间选择,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35006457/