将本地数组设置为其值

时间:2018-01-30 15:49:45

标签: bash shell

我有这两个功能:

function two() {
  local -a -x var=( ${var[@]} )
  echo "${var[@]}"
}
function one() {
  local -a -x var=(11 22 33)
  two
}

如果我打电话给那个,那么什么都没打印出来。那是为什么?

3 个答案:

答案 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)

  

什么都不打印。那是为什么?

在这两个函数中,您具有相同的标识符名称varvar中定义的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,但不能同时写两者。我更喜欢前者。