list=(1 2 3)
for i in $list; do echo $i; done;
for i in $list[@]; do echo $i; done;
for i in $list[*]; do echo $i; done;
for i in ${list}; do echo $i; done;
for i in ${list[@]}; do echo $i; done;
for i in ${list[*]}; do echo $i; done;
for i in "${list[@]}"; do echo $i; done;
Run Code Online (Sandbox Code Playgroud)
所有这些都打印相同的内容:
1
2
3
Run Code Online (Sandbox Code Playgroud)
这些
for i in "$list"; do echo $i; done;
for i in "${list}"; do echo $i; done;
for i in "$list[*]"; do echo $i; done;
for i in "${list[*]}"; do echo $i; done;
Run Code Online (Sandbox Code Playgroud)
全部打印
1 2 3
Run Code Online (Sandbox Code Playgroud)
什么时候应该使用括号、什么时候不使用括号、什么时候应该使用@括号*?例如,我知道和 之间的区别 ,但我无法找到关于, , , , , 和之间区别的直接答案。当我可以这样做时为什么要使用数组参数?"${list[@]}""${list[*]}"$list${list}$list[@]${list[@]}$list[*]${list[*]}$list
"$list"同样,当我希望数组中的所有元素都在一个字符串中时,为什么不呢?在这种情况下,我疯狂地有4 个不同的选择:"$list"、"${list}"、"$list[*]"、"${list[*]}"。
一般来说,使用哪个取决于我们。但深入研究为什么 zsh 允许编写这样的代码可能是值得的。
来自 zsh FAQ 文档:
1.2:这是什么?
Zsh 是一个 UNIX 命令解释器 (shell),它是最类似于 Korn shell (ksh) 的标准 shell;
和,
第 2 章:zsh 与...有何不同?
正如已经提到的,zsh 与 ksh 最相似,而许多添加都是为了取悦 csh 用户。
...
2.1:与sh和ksh的区别
ksh(以及 sh)的大多数功能都是在 zsh 中实现的;由于实现略有不同,可能会出现问题。
我告诉自己,当我编写自己的 zsh 脚本时,应该注意 zsh 有很多类似 ksh 的功能和模拟选项。您也可以尝试一下setopt ksh_arrays,看看发生了什么。
数组(默认情况下)比 ksh 更像 csh:下标从 1 开始,而不是 0;
array[0]指的是array[1];$array指整个数组,而不是$array[0]; 大括号是不必要的:$a[1]==${a[1]}等。设置KSH_ARRAYS兼容性选项。
它可以通过显示与 ksh 的一些比较来给出一些提示/答案。
Q22. 为什么数组引用需要大括号,例如
${x[1]}?A22。这样做固然很好
$x[1],但 POSIX shell 会展开$x,然后搜索通过连接产生的文件模式[1]。ksh 与 POSIX 兼容。
ksh 像这样处理数组参数:
list=(a b c)
echo $list[1]
;# => "a[1]"
;# concatination of the first $list element and "[1]" string
;# rather than below!
echo ${list[1]} ;# => "b"
Run Code Online (Sandbox Code Playgroud)
因此,它可以在第一个示例中使用$list、${list}、$list[@]、${list[@]}、 、$list[*]和中的任何一个;${list[*]}它可以被认为是 zsh 的一个特性。
$x[1]您可以通过阅读上面的 ksh 文档的to$list[@]或 来从另一个角度查看代码$list[*]。
注意:在 zsh 中,如果$list包含空值,则"${list[@]}"根据“ 24. 空参数删除”有所不同。
24. 空参数删除
如果替换未出现在双引号中,则任何生成的零长度参数(无论是来自标量还是数组元素)都会从插入到命令行的参数列表中删除。
@与*Q1. 例如, 和 之间
*有什么区别?@A1。当在 之外使用时
"",它们是等效的。但是,在双引号内,"$@"为每个位置参数生成一个参数,并"$*"生成单个参数。请注意,"$@"保留参数列表,而$*除非禁用分词和路径名扩展,否则可能不会。
如您所知,前半部分与 zsh 相同。这是您建议的 zsh 文档的相同参考:
形式的下标
[*]or[@]计算数组的所有元素;两者之间没有区别,除非它们出现在双引号内。
"$foo[*]"计算结果为"$foo[1] $foo[2] ...",而"$foo[@]"计算结果为"$foo[1]" "$foo[2]" ...。...
当数组参数被引用为
$name(无下标)时,其计算结果为$name[*],--- 数组下标,zshparam(1)
"$list"与其他人相比正如您所看到的,zsh 为我们提供了 4 种不同的选项作为其功能。但我认为 ksh 用户可以这样说:
"$list","${list}"并且"$list[*]"可能意味着它将仅对第一个元素(以及后者的$list连接结果)而不是列表/数组引用执行一些操作。"[*]"
这是一个示例代码:
list=(1 2 '' 3) # XXX: added an empty entry to check the difference
test-list-dq () {
echo "$1"
local i=
echo '$list:'; for i in $list; do echo $i; done;
echo '$list[@]:'; for i in $list[@]; do echo $i; done;
echo '$list[*]:'; for i in $list[*]; do echo $i; done;
echo '${list}:'; for i in ${list}; do echo $i; done;
echo '${list[@]}:'; for i in ${list[@]}; do echo $i; done;
echo '${list[*]}:'; for i in ${list[*]}; do echo $i; done;
echo '"${list[@]}":'; for i in "${list[@]}"; do echo $i; done;
}
test-list-nq () {
echo "$1"
local i=
for i in "$list"; do echo $i; done
for i in "${list}"; do echo $i; done
for i in "$list[*]"; do echo $i; done
for i in "${list[*]}"; do echo $i; done
}
echo "*double quotes"
test-list-dq "*default"
() {
setopt localoptions ksharrays no_nomatch
test-list-dq "*ksharrays on"
}
echo "*no quotes"
test-list-nq "*default"
() {
setopt localoptions ksharrays no_nomatch
test-list-nq "*ksharrays on"
}
Run Code Online (Sandbox Code Playgroud)
输出如下:
*double quotes
*default
$list:
1
2
3
$list[@]:
1
2
3
$list[*]:
1
2
3
${list}:
1
2
3
${list[@]}:
1
2
3
${list[*]}:
1
2
3
"${list[@]}":
1
2
3
*ksharrays on
$list:
1
$list[@]:
1[@]
$list[*]:
1[*]
${list}:
1
${list[@]}:
1
2
3
${list[*]}:
1
2
3
"${list[@]}":
1
2
3
*no quotes
*default
1 2 3
1 2 3
1 2 3
1 2 3
*ksharrays on
1
1
1[*]
1 2 3
Run Code Online (Sandbox Code Playgroud)