如何在 "$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(伪函数名称),如果脚本文件是来源的(例如 sourcesource ./script )。
  • 关于bash - 在 $0 和 BASH_SOURCE 之间选择,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35006457/

    10-14 03:49