考虑命令
eval false || echo ok
echo also ok
通常,我们希望它执行false
实用程序,并且由于退出状态非零,然后执行echo ok
and echo also ok
。
在我使用的所有类似 POSIX 的 shell(、、、、、OpenBSD和)ksh93
中zsh
,都会发生这种情况bash
,但如果我们启用.dash
ksh
yash
set -e
如果set -e
生效,OpenBSDsh
和ksh
shell(均源自pdksh
)将在执行eval
. 没有其他外壳可以做到这一点。
POSIX 表示特殊内置实用程序(例如eval
)中的错误应该导致非交互式 shell 终止。我不完全确定执行是否false
构成“错误”(如果是,它将与set -e
活动无关)。
解决此问题的方法似乎是将其放入eval
子外壳中,
( eval false ) || echo ok
echo also ok
问题是我是否应该在一个 POSIX-ly 正确的 shell 脚本中这样做,或者这是否是 OpenBSD 的 shell 中的一个错误?另外,上面链接的 POSIX 文本中的“错误”是什么意思?
额外信息:OpenBSD shell 将 在命令中执行echo ok
有和无set -e
eval ! true || echo ok
我的原始代码看起来像
set -e
if eval "$string"; then
echo ok
else
echo not ok
fi
使用OpenBSD 外壳不会输出(它会终止),我不确定这是设计使然,错误或误解,还是其他原因。not ok
string=false
没有其他 shell 需要这种解决方法,这强烈表明它是 OpenBSD ksh 中的一个错误。事实上,ksh93 并没有显示出这样的问题。
命令行中有 a
||
一定要避免左侧返回码 1 导致的 shell 退出。根据POSIX ,特殊内置的错误将导致非交互式 shell 退出,但这并不总是正确的。试图跳出循环是错误的,并且是内置的。但大多数外壳不会退出:
continue
continue
发出明确错误但不退出的内置函数。
因此,退出
false
是由set -e
条件而不是命令的内置特性生成的(eval
在这种情况下)。在 POSIX 中退出的确切条件
set -e
相当模糊。[对不起,如果这不是一个真正的答案,我会在找到它时更新它]
我查看了源代码,我的结论是:
1)这是一个错误/限制,背后没有任何哲学意义。
mksh
2) OpenBSD 的 ksh ( )的可移植分支对它的“修复”非常差,只会让事情变得更糟,而没有真正修复它:与所有其他 shell 不同的新错误:
仍然没有真正修复:
您可以用, , ,等替换
bash
上面的内容。dash
zsh
yash
ksh93