Behaviour of "eval" under "set -e" in conditional expression
That no other shell needs such workaround is an strong indication that it is a bug in OpenBSD ksh. In fact, ksh93 doesn't show such issue.
That there is a ||
in the command line must avoid the shell exit caused by an return code of 1 on the left side of it.
The error of an special built-in shall cause the exit of a non interactive shell acording to POSIX but that is not always true. Trying to continue
out of a loop is an error, and continue
is a builtin. But most shells do not exit on:
continue 3
A builtin that emits a clear error but doesn't exit.
So, the exit on false
is generated by the set -e
condition not by the builtin characteristic of the command (eval
in this case).
The exact conditions on which set -e
shall exit are quite more fuzzy in POSIX.
[sorry if this is not a real answer, I'll update it when I get round to it]
I had a look at the source code, and my conclusions are:
1) It's a bug/limitation, nothing philosophical behind it.
2) The "fix" for it from the portable fork of OpenBSD's ksh (mksh
) is very poor, only making things worse, without really fixing it:
New bug, different from all the other shells:
mksh -ec 'eval "false; echo yup"'
yup
bash -ec 'eval "false; echo yup"'
(nothing)
Still not really fixed:
mksh -ec 'eval "set -e; false" || echo yup'
(nothing)
bash -ec 'eval "set -e; false" || echo yup'
yup
You can replace bash
above with dash
, zsh
, yash
, ksh93
, etc.