newarray=($(echo $@)) 和 newarray=$@

newarray=($(echo $@)) 和 newarray=$@

我遵循了演示以下代码的说明'

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

相关内容