Betrachten Sie dieses Snippet:
stop () {
echo "${1}" 1>&2
exit 1
}
func () {
if false; then
echo "foo"
else
stop "something went wrong"
fi
}
Normalerweise func
führt der Aufruf dazu, dass das Skript beendet wird. Dies ist das beabsichtigte Verhalten. Wenn es jedoch in einer Sub-Shell wie in ausgeführt wird
result=`func`
Das Skript wird nicht beendet. Dies bedeutet, dass der aufrufende Code jedes Mal den Beendigungsstatus der Funktion überprüfen muss. Gibt es eine Möglichkeit, dies zu vermeiden? Ist das, was set -e
ist für?
shell
shell-script
exit
subshell
Ernest AC
quelle
quelle
func
.Antworten:
Sie könnten die ursprüngliche Shell (
kill $$
) töten, bevor Sie anrufenexit
, und das würde wahrscheinlich funktionieren. Aber:Stattdessen können Sie eine der verschiedenen Möglichkeiten verwenden, um einen Wert in den Bash-FAQ zurückzugeben . Die meisten von ihnen sind leider nicht so toll. Es kann sein, dass Sie nach jedem Funktionsaufruf nicht mehr auf Fehler überprüfen können (
-e
viele Probleme ). Entweder das, oder zu Perl wechseln.quelle
Sie können beispielsweise festlegen, dass der Beendigungsstatus 77 das Beenden einer beliebigen Subshell-Ebene bedeutet
set -E
in Kombination mitERR
Traps ist ein bisschen wie eine verbesserte Version von,set -e
in der Sie Ihre eigene Fehlerbehandlung definieren können.In zsh werden ERR-Traps automatisch vererbt, sodass Sie sie nicht benötigen
set -E
. Sie können auch Traps alsTRAPERR()
Funktionen definieren und sie$functions[TRAPERR]
wie folgt ändernfunctions[TRAPERR]="echo was here; $functions[TRAPERR]"
quelle
kill $$
.echo "$(exit 77)"
. Das Skript wirdecho ""
Alternativ dazu
kill $$
können Sie auch versuchenkill 0
, dass es bei verschachtelten Subshells funktioniert (alle Anrufer und Nebenprozesse erhalten das Signal)… aber es ist immer noch brutal und hässlich.quelle
Versuche dies ...
Die Ergebnisse, die ich bekomme, sind ...
Anmerkungen
if
Test zu ermöglichen,true
oderfalse
(siehe die 2 Läufe)if
Test istfalse
, erreichen wir nie die Unterschale.quelle
(Bash-spezifische Antwort) Bash kennt keine Ausnahmen. Wenn sich jedoch set -o errexit (oder das Äquivalent: set -e) auf der äußersten Ebene befindet, führt der fehlgeschlagene Befehl dazu, dass die Subshell mit einem Beendigungsstatus ungleich Null beendet wird. Wenn dies ein Satz verschachtelter Subshells ohne Bedingungen für die Ausführung dieser Subshells ist, wird das gesamte Skript effektiv "gerollt" und beendet.
Dies kann schwierig sein, wenn Sie versuchen, Bits verschiedener Bash-Codes in ein größeres Skript aufzunehmen. Ein Teil der Bash mag für sich alleine gut funktionieren, aber wenn es unter einem errexit (oder ohne errexit) ausgeführt wird, verhält es sich auf unerwartete Weise.
quelle
Mein Beispiel um in einem Liner auszusteigen:
quelle