我找到了一个解决方案,这个人做了http://fvue.nl/wiki/Bash:_Passing_variables_by_reference非常感谢
他。我不喜欢他使用他关于 bash 未设置的发现的方式,但任何人都可以按照自己的方式使用这个属性。所以这里是它的要点:
上面的代码在 bash 中是这样的
func_b ()
{
local var2=$1
local -i var1
#do some work to compute the value b
#....
#....
#And in the end assign it with the indirect reference
eval "$var2[1]=b"
}
func_a ()
{
local -a var1=( a )
func_b var1
echo "${var1[@]}"
}
(可以避免使用 eval,但让我们保持重点)问题显然是 func_b 中的本地 var1 遮蔽了 func_b 中的 var2 引用的 func_a 中的 var1。所以 func_b 的行为确实符合预期,即调用者数组中的第二个条目是通过间接引用添加的,只有当调用者没有将其数组命名为“var1”时。假设在“做一些工作”部分之后,我知道我已经完成了我在 func_b 中使用的局部变量 var1(可能用于计算想要的值 b)。在这一点上我可以做到这一点
func_b ()
{
local var2=$1
local -i var1
#do some work to compute the value b
#....
#....
#And in the end assign it with the indirect reference
unset var1
eval "$var2[1]=b"
}
删除 func_a 的 var1 上的“阴影”并正确终止计算。但是 bash unset 不允许这样做。一旦我在 func_b 中设置了 loval var1,即使在某些时候我取消了它,它仍然会影响 func_a 的 var1。上面的人发现,unset 实际上可以通过调用堆栈到达并取消设置 func_b 的 var1,但只有当从堆栈中 func_b 调用之上的函数 f 调用调用时,如果函数 f 没有在本地定义它自己的 var1。基本上如果你这样做
func_the_unshadower ()
{
unset -v var1
}
func_b ()
{
local var2=$1
local -i var1
#do some work to compute the value b
#....
#....
#And in the end assign it with the indirect reference
func_the_unshadower
eval "$var2[1]=b"
}
func_a ()
{
local -a var1=( a )
func_b var1
echo "${var1[@]}"
}
它有效.... 显然这只是一个玩具示例,每个人都可以找出他们喜欢的方式来使用这个 unset 属性。一个简单的方法是在运行时通过调用不带参数的“local”(返回局部变量列表)来检查名称引用的变量是否被某个局部变量遮蔽。但最棒的是,这不是 bash 中的错误。在上面的链接中,甚至还有一个指向 bash 邮件列表中一个线程的链接,主 bash 开发人员说这是 unset 的预期行为方式,它将保持这种方式。