为什么要使用zsh数组参数?

为什么要使用zsh数组参数?,zsh,Zsh,所有这些都打印相同的内容: 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; f

所有这些都打印相同的内容:

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;
这些

全部打印

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;
什么时候应该使用方括号与无方括号,以及
@
*
相比?例如,我
“${list[@]}”
“${list[*]}”
,但是我还没有找到一个简单的答案来说明
$list
${list}
$list[@]
${list[*]}
$list[*]
$list[*}
之间的区别。如果我可以只做
$list
,为什么还要使用数组参数呢

类似地,当我希望数组中的所有元素都在一个字符串中时,为什么我不干脆
“$list”
?在这种情况下,我疯狂地有了4个不同的选择:
“$list”
“${list}”
“$list[*]”
“${list[*]}”

用同样的方法试试看

1 2 3
另外,将
$IFS
设置为例如
'|'
以查看
${list[*]}
的工作方式

list=('a b' $'c\nd')

总的来说,使用哪一个取决于我们。但值得深入探究的是,为什么zsh允许编写这样的代码

来自zsh常见问题解答文档:

1.2:是什么

Zsh是一个UNIX命令解释器(shell),其中标准shell最类似于kornshell(ksh)

---

以及

第二章:zsh与……有何不同

如前所述,zsh与ksh最为相似,而许多新增功能都是为了取悦csh用户

2.1:与sh和ksh的差异

ksh(因此也是sh)的大部分功能都是在zsh中实现的;可能会出现问题,因为实现略有不同

---

我告诉自己,当我编写自己的zsh脚本时,应该注意zsh有很多类似于ksh的特性和仿真选项。你也可以试试看发生了什么

数组(默认情况下)更像csh而不是ksh:下标从1开始,而不是0<代码>数组[0]指
数组[1]
$array
指的是整个数组,而不是
$array[0]
;大括号是不必要的:
$a[1]
=
${a[1]}
等。设置兼容性选项

---

它可以通过显示与ksh的一些比较来给出一些提示/答案

括号与无括号 问题22。为什么数组引用需要大括号,例如。g<代码>${x[1]}

A22。执行
$x[1]
会很好,但是POSIX shell会展开
$x
,然后通过连接
[1]
搜索文件模式。ksh与POSIX兼容

---

ksh对数组参数的处理方式如下:

list=('a b' $'c\nd')
IFS='|'
printf %s "${list[*]}"
因此,在第一个示例中,它可以使用
$list
${list}
$list[@]
${list[@]}
$list[*]
${list[*}
中的任何一个;这可以看作是zsh的特征

您可以从另一个角度查看代码,方法是阅读ksh文档上方的
$x[1]
$list[@]
$list[*]

注意:在zsh中,如果
$list
包含空值,
“${list[@]}”
根据“”不同

二十四,。空参数删除

如果替换未出现在双引号中,则从插入到命令行的参数列表中删除任何产生的零长度参数,无论是来自标量还是数组元素

---

@
*
问题1。例如,
*
@
之间的区别是什么

A1。当在
之外使用时,它们是等效的。但是,在双引号中,
“$@”
为每个位置参数生成一个参数,
“$*”
生成一个参数。请注意,
“$@”
保留参数列表,而
$*
可能不保留参数列表,除非同时禁用了分词和路径名扩展

---

正如你所知,这前半部分与zsh相同。以下是您建议的zsh文件的相同参考:

[*]
[@]
形式的下标计算数组的所有元素;两者之间没有区别,除非它们出现在双引号内

“$foo[*]”
的计算结果为
“$foo[1]$foo[2]…”
”,而
“$foo[@]”
的计算结果为
“$foo[1]”“$foo[2].”

当数组参数被引用为
$name
(无下标)时,其计算结果为
$name[*]

---

“$list”
与其他 正如您所看到的,已经很清楚了,zsh为我们提供了4种不同的选项作为其功能。但我认为ksh用户可以这样说:

“$list”
“${list}”
“$list[*]”
可能意味着它将只对
$list
的第一个元素(以及对后者合并
“[*]”
的结果)执行一些操作,而不是列表/数组引用


下面是一个示例代码:

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"
产出如下:

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"
}

这只发生在zsh中,而不是bash中,因此我删除了bash标记
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"
}
*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