小编典典

在 $0 和 BASH_SOURCE 之间选择

all

如何在"$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]}

阅读 62

收藏
2022-07-14

共1个答案

小编典典

注意:对于 符合 POSIX 的 解决方案,请参阅此答案

${BASH_SOURCE[0]}(或更简单地说,$BASH_SOURCE[1] )在 所有 调用场景
中包含包含脚本的(可能是相对的)路径,尤其是当脚本是 source 时,这对于$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]}对比$BASH_SOURCE

Bash 允许您使用 标量0表示法来引用数组变量的 元素 :您可以编写;而不是写; 换句话说:如果您将变量引用 为标量 ,您将获得
index 处的元素。 ${arr[0]}``$arr 0

使用此功能会掩盖数组这一事实$arr,这就是流行的 shell-code linter
shellcheck.net发出以下警告的原因(截至撰写本文时):

SC2128:扩展没有索引的数组只给出第一个元素。

附带说明:虽然此警告很有帮助,但它可能更精确,因为您不一定会得到第 一个 元素:它特别0是返回的索引处的元素,所以如果第一个元素具有更高的索引 -在
Bash 中是可能的 - 你会得到空字符串;试试'a[1]='hi'; echo "$a"'
(相比之下,zsh叛徒确实 返回 第一个元素,而不管其索引如何)。

由于其晦涩难懂,您可能会选择避开此功能,但它的工作原理是可预测的,而且从实用的角度讲,您很少需要访问数组变量 以外
的索引。0``${BASH_SOURCE[@]}


可选阅读,第 2 部分:在什么情况下,BASH_SOURCE数组变量实际上包含 多个 元素?

BASH_SOURCE 如果涉及函数调用,则 只有多个条目,在这种情况下,它的元素与FUNCNAME包含 当前调用堆栈上的
所有函数名称的数组平行。

也就是说,在函数内部,${FUNCNAME[0]}包含执行函数的名称${BASH_SOURCE[0]},包含定义该函数的脚本文件的路径,${FUNCNAME[1]}包含调用当前执行函数的函数的名称(如果适用),等等上。

如果给定函数是直接从脚本文件的顶级范围调用的,该脚本文件$i在调用堆栈级别定义了该函数,则${FUNCNAME[$i+1]}包含:

  • main(伪函数名称),如果脚本文件被 直接 调用(例如,./script

  • source(伪函数名称),如果脚本文件是 来源 (例如source ./script. ./script)。

2022-07-14