Ash、Dash或Bash、Zsh以不同方式处理here-document中的无效空参数${var:?}
扩展错误。
下面是使用真正POSIX语法的experiment.sh
代码:
#!/usr/bin/env sh
empty_var=
read -r value << EOF
Expected fail here ${empty_var:?}"
EOF
printf '$?=%d\nvalue=%s\n' $? "$value"
下面是使用不同shell运行实验的代码:
for sh in ash bash dash ksh zsh; do
printf 'Testing with: %s\n' "$sh"
LC_ALL=C "$sh" ./experiment.sh || :
echo
done
获得的结果:
Testing with: ash
./experiment.sh: 5: empty_var: parameter not set or null
$?=2
value=
Testing with: bash
./experiment.sh: line 5: empty_var: parameter null or not set
Testing with: dash
./experiment.sh: 5: empty_var: parameter not set or null
$?=2
value=
Testing with: ksh
./experiment.sh[5]: empty_var: parameter null
$?=1
value=
Testing with: zsh
./experiment.sh:5: empty_var: parameter not set
Bash和Zsh立即停止执行,而其他shell继续执行,只是引发返回代码$?
。
对于这种与真正的POSIX语法结构的行为差异,有什么解释呢?
是否记录了为什么Bash或Zsh选择退出脚本而不是返回Ksh、Dash或Ash这样的失败代码?
请注意,在其他上下文中(如字符串中的扩展),所有shell都退出脚本。
据我所知,行为差异只发生在这里的文档中。
2条答案
按热度按时间yvgpqqbh1#
相关的POSIX文档似乎在Open Group Shell Command Language文档的参数扩展部分。
${parameter:?[word]}
**Null或Unset表示错误。**如果 parameter 为unset或null,则 word 的展开(或如果省略 word 则表示未设置)将写入标准错误,shell以非零退出状态退出。否则,parameter 的值将被替换。交互式shell无需退出。
我对它的阅读是非交互式shell需要立即退出。我找不到任何建议它应该在here-documents中有不同的行为。看起来你发现了一个影响多个shell的bug。
5us2dqdw2#
对于bash,它记录为
here
:${parameter:?word}
如果parameter为null或unset,则word的扩展(或如果word不存在则显示相应的消息)将写入标准错误,如果shell不是交互式的,则退出。否则,将替换parameter的值。
here
是zsh文档。