所有测试的 shell 都使用以下代码对(引用的)“$*”和“$@”对执行相同的操作:
c='set a b @ c; IFS=:,@ ; a=$(printf "<%s> " "$*"); b=$(printf "<%s> " "$@"); printf "%-20s and %-20s\n" "$a" "$b"'
d=(sh ash dash attsh ksh lksh mksh bash b44sh y2sh zsh zsh4 "zsh -y")
for shell in "${d[@]}"; do
printf '%15s: ' "$shell"
$shell -c "$c"
done
结果:
sh: <a:b:@:c> and <a> <b> <@> <c>
ash: <a:b:@:c> and <a> <b> <@> <c>
dash: <a:b:@:c> and <a> <b> <@> <c>
attsh: <a:b:@:c> and <a> <b> <@> <c>
ksh: <a:b:@:c> and <a> <b> <@> <c>
lksh: <a:b:@:c> and <a> <b> <@> <c>
mksh: <a:b:@:c> and <a> <b> <@> <c>
bash: <a:b:@:c> and <a> <b> <@> <c>
b44sh: <a:b:@:c> and <a> <b> <@> <c>
y2sh: <a:b:@:c> and <a> <b> <@> <c>
zsh: <a:b:@:c> and <a> <b> <@> <c>
zsh4: <a:b:@:c> and <a> <b> <@> <c>
zsh -y: <a:b:@:c> and <a> <b> <@> <c>
但是,对于未引用的$*
和$@
测试(只$c
需要更改):
c='set a b @ c; IFS=:,@ ; a=$(printf "<%s> " $*); b=$(printf "<%s> " $@); printf "%-20s and %-20s\n" "$a" "$b"'
结果是:
sh: <a> <b> <> <> <c> and <a> <b> <> <> <c>
ash: <a> <b> <> <> <c> and <a> <b> <> <> <c>
dash: <a> <b> <> <> <c> and <a> <b> <> <> <c>
attsh: <a> <b> <> <c> and <a> <b> <> <c>
ksh: <a> <b> <> <c> and <a> <b> <> <c>
lksh: <a> <b> <> <> <c> and <a> <b> <> <> <c>
mksh: <a> <b> <> <> <c> and <a> <b> <> <> <c>
bash: <a> <b> <> <> <c> and <a> <b> <> <> <c>
b44sh: <a> <b> <> <> <c> and <a> <b> <> <> <c>
y2sh: <a> <b> <> <> <c> and <a> <b> <> <> <c>
zsh: <a> <b> <@> <c> and <a> <b> <@> <c>
zsh4: <a> <b> <@> <c> and <a> <b> <@> <c>
zsh -y: <a> <b> <> <> <c> and <a> <b> <@> <c>
撇开 ksh 中删除重复值不谈,除了 zsh 之外,所有 shell 的行为方式都是相同的。其中呈现了一个@
.如果默认情况下引用变量(或者默认情况下不执行拆分),这可能是合理的。
但是在尝试获取所有其他 shell 的默认值并要求 zsh 拆分(取消引用)所使用的变量时,我们得到了不同的值$*
和$@
再次更改$c
为:
c='set a b @ c; IFS=:,@ ; a=$(printf "<%s> " $*); b=$(printf "<%s> " $@); [ "$a" = "$b" ] && echo "Yes" || echo "Nope"'
我们得到这个明确的结果:
sh: Yes
ash: Yes
dash: Yes
attsh: Yes
ksh: Yes
lksh: Yes
mksh: Yes
bash: Yes
b44sh: Yes
y2sh: Yes
zsh: Yes
zsh4: Yes
zsh -y: Nope
只有 zsh 没有不带引号(分割)$*
和$@
等于。
答案1
那是一个漏洞(回归)在zsh-4.3.11-dev-4版本中引入2011 年,现在由这个变更集。
该修复现已包含在 5.3 版本(2016 年 12 月 11 日发布)及更高版本中。该错误影响版本 4.3.11-dev-4 至 5.2。