此处文档中空参数的 shell 行为差异

Léa*_*ris 8 bash shell ksh posix behavior

${var:?}Ash、Dash 或 Bash、Zsh以不同的方式处理此处文档中的无效空参数扩展错误。

下面是experiment.sh使用真正的 POSIX 语法的代码:

#!/usr/bin/env sh

empty_var=

read -r value << EOF
Expected fail here ${empty_var:?}"
EOF
printf '$?=%d\nvalue=%s\n' $? "$value"
Run Code Online (Sandbox Code Playgroud)

下面是使用不同 shell 运行实验的代码:

for sh in ash bash dash ksh zsh; do
  printf 'Testing with: %s\n' "$sh"
  LC_ALL=C "$sh" ./experiment.sh || :
  echo
done
Run Code Online (Sandbox Code Playgroud)

得到的结果:

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
Run Code Online (Sandbox Code Playgroud)

Bash 和 Zsh 立即停止执行,而其他 shell 继续执行,只是引发返回码$?

对于这种与真正的 POSIX 语法结构的行为差异,有什么解释?

是否有记录为什么 Bash 或 Zsh 选择退出脚本而不是像 Ksh、Dash 或 Ash 那样返回失败代码?

请注意,在其他上下文(例如字符串扩展)中,所有 shell 都会退出脚本。

据我所知,行为差异仅出现在此处文档中。

pjh*_*pjh 4

相关的 POSIX 文档似乎位于Open Group Shell 命令语言文档的参数扩展部分。

${parameter:?[word]}
如果为 Null 或未设置,则指示错误。如果参数未设置或为空,则单词的扩展(或者如果省略单词则指示未设置的消息)应写入标准错误,并且 shell 以非零退出状态退出。否则,应替换参数的值。交互式 shell 不需要退出。

我的理解是非交互式 shell 需要立即退出。我找不到任何表明它应该在此处文档中表现不同的内容。您似乎发现了一个影响多个 shell 的错误。