Bash:本地数组阴影参数最终为空
我刚刚注意到(偶然地)对于Bash:本地数组阴影参数最终为空,bash,Bash,我刚刚注意到(偶然地)对于bash,如果我在函数中使用一个局部数组来保存作为参数传递的数组,并将该局部数组的名称与传递给该函数的全局参数的名称相同,则局部数组最终为空。这听起来有点复杂,下面是一个例子: foo() { declare -a bar=("${!1}") echo "${bar[@]}" } bar=(1 2 3) foo bar[@] 在我的系统上,运行gnubash4.4.23的Linux会打印一条换行符。但是,以下两种变体都输出1 2 3: foo() {
bash
,如果我在函数中使用一个局部数组来保存作为参数传递的数组,并将该局部数组的名称与传递给该函数的全局参数的名称相同,则局部数组最终为空。这听起来有点复杂,下面是一个例子:
foo() {
declare -a bar=("${!1}")
echo "${bar[@]}"
}
bar=(1 2 3)
foo bar[@]
在我的系统上,运行gnubash4.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[@]}”
- 当您声明一个local时,它将开始为空
- 间接变量引用使用查找时在范围内的名称——这意味着,它们将在具有相同名称的非空全局之前匹配空局部
foobar[@]
在任何方面都不会传递当前范围中存在的“${bar[@]}”的内容,而只是传递字符串bar[@]
(如果幸运的话;如果当前目录中存在名为bar@
的文件,则可以将其扩展为glob)。当在函数的上下文中对bar[@]
进行间接查找时,bar
是一个本地函数。。。这是你的问题
因此,一个更具参考价值的工作方案示例如下:
foo() {
declare -a local_bar=("${!1}")
echo "${local_bar[@]}"
}
bar=(1 2 3)
foo 'bar[@]'
…您的本地计算机具有不同的名称(local\u bar
),因此,全局不受空局部的影响。本问题中给出的任何工作备选方案的输出都不依赖于任何成功的间接扩展——它们都直接从echo
行引用全局变量bar
。(前者根本不设置任何局部变量;后者设置一个局部变量,但不以任何方式使用它)。是的,我的错,第二个例子应该是echofoobar
,我会解决这个问题。(顺便说一句,您在这里提出的问题也适用于namevar,这就是为什么在函数中定义namevar的人为了名称空间的目的而将其作为前缀被认为更可取的原因:declare-n myfunc_foo=$1
即使在$1
中命名的数组是foo
也可以工作)。