我遵循了演示以下代码的说明'
function testit()
{
local newarray
newarray=($(echo $@))
echo "The new array value is: ${newarray[*]}"
}
myarray=(1 2 3 4 5)
echo "The original array is ${myarray[*]}"
testit ${myarray[*]}
我很好奇newarray=$(echo $@)
指令的另一个例子arg1=$(echo ${myarray[*]})
newarray=$@
直接又直观,多花点功夫有什么好处。
答案1
这些都不能正常工作:
a=($(echo $@))
b=$@
第一个展开$@
和分词和通配符,因此带有空格的值不会保持完整,任何看起来像通配符的东西都会扩展。
第二个将整个数组折叠成单个标量值,数组元素用空格 (Bash/ksh) 或IFS
(Busybox/dash/Zsh; 与"$*"
) 的第一个字符连接。
从概念上讲,$@
在标量上下文中使用也感觉不对。它用于扩展为值列表,但这里我们不能有一个值列表。如果您确实想连接数组元素,我建议s="$*"
显式使用。 (引号有助于避免某些 shell 中的错误。)
例如:
$ touch file1 file2
$ set -- "foo bar" "*"
$ a=($(echo $@))
$ declare -p a
declare -a a=([0]="foo" [1]="bar" [2]="file1" [3]="file2")
和
$ b=$@
$ declare -p b
declare -- b="foo bar *"
$@
制作数组副本的更好方法是
c=("$@")
c=("${myarray[@]}")
尽管这两者都会将数组索引折叠为从零开始(注意*
之前和之后的索引):
$ unset l; l[0]="foo bar"; l[2]="*"
$ c=("${l[@]}")
$ declare -p c
declare -a c=([0]="foo bar" [1]="*")
不过,这通常不是问题,因为您不会意外获得具有不连续索引的数组。
答案2
newarray=$@
会将整个$@
字符串分配给单个标量变量newarray
,而不是数组。
使用“命令替换”echo
也是毫无意义的。您将成功分配一个数组,newarray=($@)
正如您在输出数组的元素计数时所看到的那样
newarray=($@); echo "The new array value is: ${newarray[*]}, ${#newarray[@]}"
The new array value is: 1 2 3 4 5, 5
相对于
newarray=$@; echo "The new array value is: ${newarray[*]}, ${#newarray[@]}"
The new array value is: 1 2 3 4 5, 1