我们说我有一个脚本echoargs
$ echo $#
$ echo $*
我可以在数组扩展周围加上引号并获得此行为:
$ arr=("a b" "c d" "e f")
$ echoargs "${arr[@]}"
3
a b c d e f
或者我不能引用并引发此行为:
$ echoargs ${arr[@]}
6
a b c d e f
然后是这段代码:
$ for i in "q ${arr[@]} q"; do echo $i; done
q a b
c d
e f q
答案 0 :(得分:2)
真的没有任何神奇的事情发生,它只是在引用。
for i in "q ${arr[@]} q"
是相同的
for i in "q ""${arr[@]}"" q"
与for i in "q ""a b" "c d" "e f"" q"
相同,与for i in "q a b" "c d" "e f q"
echoargs ${arr[@]}
与echoargs a b c d e f
echoargs "${arr[@]}"
与echoargs "a b" "c d" "e f"
答案 1 :(得分:1)
https://www.gnu.org/software/bash/manual/bashref.html#Arrays:
可以使用
${name[subscript]}
引用数组的任何元素。需要大括号以避免与shell的文件名扩展运算符冲突。如果下标是'@'或'*',则该单词将扩展为数组 name 的所有成员。这些下标仅在单词出现在双引号内时有所不同。 如果单词是双引号,${name[*]}
会扩展为单个单词,每个数组成员的值由IFS
变量的第一个字符分隔,${name[@]}
将 name 的每个元素扩展为单独的单词。如果没有数组成员,${name[@]}
会扩展为空。 如果在单词中出现双引号扩展,则第一个参数的扩展与原始单词的开头部分连接,最后一个参数的扩展与原始单词的最后部分连接。 / strong>这类似于特殊参数'@'和'*'的扩展。
(强调我的。)
答案 2 :(得分:0)
使用echoargs
的不同版本:
echoargs() { echo $#; printf '[%s]\n' "$@"; }
arr=("a" "b c" " d e f " " multiple
lines too")
echoargs ${arr[@]}
echoargs "${arr[@]}"
echoargs ${arr[*]}
echoargs "${arr[*]}"
当我运行时,我得到输出:
$ echoargs() { echo $#; printf '[%s]\n' "$@"; }
$ arr=("a" "b c" " d e f " " multiple
> lines too")
$ echoargs ${arr[@]}
9
[a]
[b]
[c]
[d]
[e]
[f]
[multiple]
[lines]
[too]
$ echoargs "${arr[@]}"
4
[a]
[b c]
[ d e f ]
[ multiple
lines too]
$ echoargs ${arr[*]}
9
[a]
[b]
[c]
[d]
[e]
[f]
[multiple]
[lines]
[too]
$ echoargs "${arr[*]}"
1
[a b c d e f multiple
lines too]
$
基本上,"${arr[@]}"
形式保留了数组元素的内部间距。两个未加引号的形式都丢失了所有内部间距信息,并将数组元素拆分为一个或多个空格的序列。 "${arr[*]}"
表示法保留内部空格,但组合所有元素以形成单个字符串,并在值之间留出空格。
您使用的是适合您需要的符号,但通常使用"${arr[@]}"
符号是正确的。