Betrachten Sie die Befehle
eval false || echo ok
echo also ok
Normalerweise würden wir erwarten , dass dies das auszuführen false
Dienstprogramm , und da der Exit - Status ungleich Null ist, dann ausführen echo ok
und echo also ok
.
In allen POSIX-wie Muscheln ich ( ksh93
, zsh
, bash
, dash
, OpenBSD ksh
, und yash
), das ist , was passiert, aber die Dinge interessant , wenn wir ermöglichen set -e
.
Wenn dies der set -e
Fall ist, beenden OpenBSDs sh
und ksh
Shells (beide abgeleitet von pdksh
) das Skript, wenn das ausgeführt wird eval
. Keine andere Shell macht das.
Laut POSIX sollte ein Fehler in einem speziellen integrierten Dienstprogramm (z. B. eval
) dazu führen, dass die nicht interaktive Shell beendet wird. Ich bin mir nicht ganz sicher, ob das Ausführen false
"einen Fehler" darstellt (wenn dies der Fall wäre, wäre es unabhängig davon set -e
, aktiv zu sein).
Der Weg, dies zu umgehen, scheint darin zu bestehen, das eval
in eine Sub-Shell zu setzen.
( eval false ) || echo ok
echo also ok
Die Frage ist, ob ich das in einem POSIX-korrekten Shell-Skript tun muss oder ob es ein Fehler in der OpenBSD-Shell ist. Was ist mit "Fehler" im oben verlinkten POSIX-Text gemeint?
Zusätzliche Informationen: Die OpenBSD-Shells führen echo ok
sowohl mit als auch ohne set -e
im Befehl aus
eval ! true || echo ok
Mein ursprünglicher Code sah aus wie
set -e
if eval "$string"; then
echo ok
else
echo not ok
fi
Dies würde bei Verwendung der OpenBSD-Shells nicht ausgegeben werden (es würde enden), und ich war mir nicht sicher, ob es beabsichtigt, versehentlich oder durch Missverständnisse oder etwas anderes war.not ok
string=false
eval false
, das Skript zu beenden, auch wenn es Teil einer UND-ODER-Liste oder einer bedingten Anweisung ist? Ich würde nicht.
set -e
ist, ob dies das richtige Verhalten ist ... Ich stimme zu, dass es sinnvoll ist, nicht in einer bedingten Anweisung zu beenden.
set -e
also ist das `()` die Antwort.
eval false
generiert einen Status ungleich Null, sodass ich erwarten würdeset -e
, das Skript an diesem Punkt zu beenden. Im Falle von!
set -e
gilt nicht, da die!
Anweisung den Exit-Status explizit überprüft.