bash 在 $0 和 BASH_SOURCE 之间选择
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/35006457/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
choosing between $0 and BASH_SOURCE
提问by H2ONaCl
How does one choose between "$0"
and "${BASH_SOURCE[0]}"
如何在"$0"
和之间选择"${BASH_SOURCE[0]}"
This description from GNUdidn't help me much.
来自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]}
回答by mklement0
Note: For a POSIX-compliant solution, see this answer.
注意:有关符合 POSIX 的解决方案,请参阅此答案。
${BASH_SOURCE[0]}
(or, more simply, $BASH_SOURCE
[1]) contains the (potentially relative) path of the containing script in allinvocation scenarios, notably also when the script is sourced, which is not true for $0
.
${BASH_SOURCE[0]}
(或者,更简单地说,$BASH_SOURCE
[1])包含所有调用场景中包含脚本的(可能是相对的)路径,特别是当脚本是source 时,这对于$0
.
Furthermore, as Charles Duffypoints out, $0
can be set to an arbitraryvalue by the caller.
On the flip side, $BASH_SOURCE
canbe empty, if no named file is involved; e.g.:echo 'echo "[$BASH_SOURCE]"' | bash
此外,正如Charles Duffy指出的那样,调用者$0
可以将其设置为任意值。
另一方面,如果不涉及命名文件,$BASH_SOURCE
则可以为空;例如:echo 'echo "[$BASH_SOURCE]"' | bash
The following example illustrates this:
以下示例说明了这一点:
Script foo
:
脚本foo
:
#!/bin/bash
echo "[$ bash ./foo
[./foo] vs. [./foo]
$ ./foo
[./foo] vs. [./foo]
$ . ./foo
[bash] vs. [./foo]
] vs. [${BASH_SOURCE[0]}]"
$ cat outer.sh
#!/usr/bin/env bash
./middle.sh
$0
is part of the POSIX shell specification, whereas BASH_SOURCE
, as the name suggests, is Bash-specific.
$0
是 POSIX shell 规范的一部分,而BASH_SOURCE
,顾名思义,是 Bash 特定的。
[1] Optional reading: ${BASH_SOURCE[0]}
vs. $BASH_SOURCE
:
[1]可选读物:${BASH_SOURCE[0]}
vs.$BASH_SOURCE
:
Bash allows you to reference element 0
of an arrayvariable using scalarnotation: instead of writing ${arr[0]}
, you can write $arr
; in other words: if you reference the variable as if it were a scalar, you get the element at index 0
.
击允许你参考元件0
的的阵列变量使用标量表示法:代替书写的${arr[0]}
,可以编写$arr
; 换句话说:如果你像引用一个 scalar 一样引用变量,你就会得到 index 处的元素0
。
Using this feature obscures the fact that $arr
is an array, which is why popular shell-code linter shellcheck.netissues the following warning (as of this writing):
使用此功能掩盖了$arr
数组的事实,这就是流行的 shell-code linter shellcheck.net发出以下警告的原因(在撰写本文时):
SC2128: Expanding an array without an index only gives the first element.
SC2128:扩展没有索引的数组只给出第一个元素。
On a side note: While this warning is helpful, it could be more precise, because you won't necessarily get the firstelement: It is specifically the element at index 0
that is returned, so if the first element has a higher index - which is possible in Bash - you'll get the empty string; try 'a[1]='hi'; echo "$a"'
.
(By contrast, zsh
, ever the renegade, indeed doesreturn the first element, irrespective of its index).
附带说明:虽然此警告很有帮助,但它可能更准确,因为您不一定会获得第一个元素:特别0
是返回索引处的元素,因此如果第一个元素具有更高的索引 - 哪个在 Bash 中是可能的 - 你会得到空字符串;试试'a[1]='hi'; echo "$a"'
。
(相比之下,zsh
, 曾经的叛徒,确实会返回第一个元素,而不管其索引如何)。
You may choose to eschew this feature due to its obscurity, but it works predictably and, pragmatically speaking, you'll rarely, if ever, need to access indices otherthan 0
of array variable ${BASH_SOURCE[@]}
.
您可以选择避开这一功能,因为它默默无闻,但它的工作原理可以预见和务实地讲,你会很少,如果有的话,需要访问索引其他比0
数组变量${BASH_SOURCE[@]}
。
回答by Huw Walters
These scripts may help illustrate. The outer script calls the middle script, which calls the inner script:
这些脚本可能有助于说明。外部脚本调用中间脚本,中间脚本调用内部脚本:
$ cat middle.sh
#!/usr/bin/env bash
./inner.sh
$ cat inner.sh
#!/usr/bin/env bash
echo "$0 = '$ ./outer.sh
$ cat outer.sh
#!/usr/bin/env bash
source ./middle.sh
= './inner.sh'
$BASH_SOURCE[0] = './inner.sh'
$BASH_SOURCE[1] = ''
$BASH_SOURCE[2] = ''
'"
echo "${BASH_SOURCE[0]} = '${BASH_SOURCE[0]}'"
echo "${BASH_SOURCE[1]} = '${BASH_SOURCE[1]}'"
echo "${BASH_SOURCE[2]} = '${BASH_SOURCE[2]}'"
$ cat middle.sh
#!/usr/bin/env bash
source ./inner.sh
$ cat inner.sh
#!/usr/bin/env bash
echo "$0 = '$ ./outer.sh
##代码## = './outer.sh'
$BASH_SOURCE[0] = './inner.sh'
$BASH_SOURCE[1] = './middle.sh'
$BASH_SOURCE[2] = './outer.sh'
'"
echo "${BASH_SOURCE[0]} = '${BASH_SOURCE[0]}'"
echo "${BASH_SOURCE[1]} = '${BASH_SOURCE[1]}'"
echo "${BASH_SOURCE[2]} = '${BASH_SOURCE[2]}'"
However, if we change the script calls to source
statements:
但是,如果我们将脚本调用更改为source
语句: