重击:本地数组阴影参数最终为空

时间:2018-12-15 21:39:57

标签: bash

我刚刚(偶然)注意到,如果使用bash,如果我在函数内使用本地数组来保存作为参数传递的数组,并给该本地数组起传递给全局参数的相同名称,该函数,本地数组最终为空。这听起来有点令人费解,所以这里有个例子:

foo() {
    declare -a bar=("${!1}")
    echo "${bar[@]}"
}

bar=(1 2 3)
foo bar[@]

在我的系统上,运行GNU bash 4.4.23的Linux将打印换行符。但是,以下两个变体都输出1 2 3

foo() {
    echo "${bar[@]}"
}

bar=(1 2 3)
foo bar[@]

以及:

foo() {
    declare -a foobar=("${!1}")
    echo "${foobar[@]}"
}

bar=(1 2 3)
foo bar[@]

我想知道为什么会这样,我想这与bash如何执行名称解析有关,但我不确定。请注意,我并不是在寻找其他方法来做与我想解释的相同的事情。

编辑:第三个被剪断的先前包含echo "${bar[@]}",但应该已经读过echo "${foobar[@]}"

1 个答案:

答案 0 :(得分:1)

  • 声明本地语言时,它开始为空。
  • 间接变量引用使用在查找时处于作用域内的名称-这意味着,它们将与一个空的本地名称匹配,然后与一个具有相同名称的非空全局名称匹配。

...这也意味着foo bar[@]在任何方面都不传递"${bar[@]}"的内容,因为它存在于当前范围中,而只是传递字符串{{1} }(如果幸运的话;如果当前目录中存在名为bar[@]的文件,则可以将其扩展为glob)。在bar@是本地函数的情况下,如果在bar[@]上进行间接查找...那么,这就是您的问题。


因此,一个可行的替代方案的更多信息示例是:

bar

...您的本地名称(foo() { declare -a local_bar=("${!1}") echo "${local_bar[@]}" } bar=(1 2 3) foo 'bar[@]' )不同,因此全局不会被空的本地阴影遮盖。