我有这两个功能:
function two() {
local -a -x var=( ${var[@]} )
echo "${var[@]}"
}
function one() {
local -a -x var=(11 22 33)
two
}
如果我打电话给那个,那么什么都没打印出来。那是为什么?
答案 0 :(得分:3)
您的代码并未反映您要执行的操作!您定义的本地人仅在 范围内功能是的!但如果您将其传递给另一个函数,则将其作为位置参数"$@"
传递。在执行two "${var[@]}"
时,在下面的函数中,您将本地数组作为位置参数数组传递,以便在另一个函数中使用。
two() {
local -a -x var=( "$@" )
echo "${var[@]}"
}
参数列表"$@"
表示传递给函数two
的参数列表,现在从函数one
传递给
one() {
local -a -x var=(11 22 33)
two "${var[@]}"
}
function
关键字的使用也是非标准的。 POSIX不建议使用它。如果您计划为多个shell重用脚本,请删除关键字。同时引用变量/数组以避免它们被字符串分割和全局扩展。它可能会导致最终数组中的意外值。
另外值得注意的是,默认情况下变量/数组是全局的,除非你在函数内覆盖local
个关键字。
$ x=2
$ test_local(){ local x=1; }
$ test_local; echo "$x"
2
但没有local
的情况会将值打印为1
,这证明了上述问题。
答案 1 :(得分:3)
什么都不打印。那是为什么?
在这两个函数中,您具有相同的标识符名称var
您var
中定义的one
可由two
访问,因为two
是从one
调用的。但是,
在单个命令中声明和设置局部变量时, 显然,操作的顺序是先设置变量,然后 之后才将其限制在当地范围内。
所以在
local -a -x var=( "${var[@]}" )
${var[@]}
部分将为空,因为变量var
首先设置为本地。
要验证这一点,您可以将one
中的变量名称更改为var1
,并将two
更改为
local -a -x var=( "${var1[@]}" ) # var1 though local to one should be accessible here.
您可以使用@ inian' s answer作为解决方案轻松传递变量,而不是打扰bash中的这些黑暗角落。
答案 2 :(得分:1)
当您在var
中声明two
时,该声明会隐藏one
中的声明。奇怪的是,局部变量在被调用函数中可见。最简单的方法就是不做任何事情:只需访问$var
中的two
。
two() {
echo "${var[@]}"
}
one() {
local var=(11 22 33)
two "${var[@]}"
}
但是,我不一定建议这样做。通过阅读它很难理解two
的作用。最好将值显式传递为参数。
two() {
local var=("$@")
echo "${var[@]}"
}
one() {
local var=(11 22 33)
two "${var[@]}"
}
顺便说一句,你应该总是引用你的变量扩展来防止它们受到单词拆分和通配。在原始代码中,您应引用${var[@]}
:
local -a -x var=( "${var[@]}" )
另外,为了便于携带,您应该写one()
或function one
,但不能同时写两者。我更喜欢前者。