Betrachten Sie die Befehle
eval false || echo ok
echo also ok
Normalerweise würden wir erwarten , dass dies das auszuführen falseDienstprogramm , und da der Exit - Status ungleich Null ist, dann ausführen echo okund 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 -eFall ist, beenden OpenBSDs shund kshShells (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 evalin 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 oksowohl 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 okstring=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 -eist, ob dies das richtige Verhalten ist ... Ich stimme zu, dass es sinnvoll ist, nicht in einer bedingten Anweisung zu beenden.
set -ealso ist das `()` die Antwort.
eval falsegeneriert einen Status ungleich Null, sodass ich erwarten würdeset -e, das Skript an diesem Punkt zu beenden. Im Falle von!set -egilt nicht, da die!Anweisung den Exit-Status explizit überprüft.