Der Code sollte wie erwartet funktionieren, lassen Sie uns dies demonstrieren:
#!/usr/bin/env bash
set -e
var="test"
if [[ $var = test ]]; then
echo "Hello"
cat non_existing_file &> /dev/null
echo "World"
else
echo "Else hello"
cat non_existing file &> /dev/null
fi
echo I am done
Dies wird nur ausgegeben, "Hallo", wie erwartet. Wenn es für Sie anders funktioniert, bedeutet dies, dass Sie nicht genügend Code zur Verfügung gestellt haben. Lassen Sie uns versuchen, den Code oben zu ändern und einige Beispiele zeigen, wenn set -e
ignoriert wird, wie in Ihrem Fall:
Bash Reference manual Zitiert:
Wenn eine Verbindung Befehl oder Shell-Funktion in einem Kontext ausgeführt wird, wo -e wird ignoriert, keiner der Befehle, die in dem zusammengesetzten Befehls- oder Funktionskörper ausgeführt werden, wird von der Einstellung -e beeinflusst, selbst wenn -e gesetzt ist und ein Befehl einen Fehlerstatus zurückgibt.
Nun wollen wir das gleiche Handbuch zitieren und einige Fälle sehen, wo -e ignoriert wird:
Die Schale wird nicht beendet, wenn der Befehl, der Teil Liste der Befehl schlägt fehl, sofort nach einer Weile oder bis Schlüsselwort, Teil von der Test in einer if-Anweisung, Teil eines beliebigen Befehls in einem & & oder || ausgeführte Liste mit Ausnahme des Befehls nach dem letzten & & oder ||, einem beliebigen Befehl in einer Pipeline, aber der letzte, oder wenn der Rückgabestatus des Befehls ist invertiert mit!.
Daraus können wir, dass zum Beispiel sehen, wenn Sie den Code oben in einer Funktion haben und getestet, diese Funktion mit if
würde set -e
außer Acht gelassen werden:
#!/usr/bin/env bash
set -e
f() {
var="test"
if [[ $var = test ]]; then
echo "Hello"
cat non_existing_file &> /dev/null
echo "World"
else
echo "Else hello"
cat non_existing file &> /dev/null
fi
}
if f; then echo "Function OK!"; fi
echo I am done
Funktion f
wird in einem ausgeführt Kontext, in dem set -e
ignoriert wird (if-Anweisung), was bedeutet, dass set -e
keinen der in dieser Funktion ausgeführten Befehle beeinflusst. Dieser Code gibt:
Hallo
Welt
Funktion OK!
Ich
getan
Die gleichen Regeln gelten, wenn Sie die Funktion in einem & & oder ausführen || Liste. Wenn Sie die Zeile if f; then echo "Function OK!"; fi
zu f && echo "Function OK"
ändern, erhalten Sie die gleiche Ausgabe. Ich glaube, Letzteres könnte Ihr Fall sein.
Trotzdem Ihre zweite Frage leicht || exit
durch Zugabe gelöst werden:
run_test1 || exit 1;
run_test2 || exit 1;
Ihre erste Frage trivial ist, wenn Sie in einer Funktion zum Beispiel sind. Dann kannst du einfach return
. Oder in einer Schleife, dann können Sie break
. Wenn Sie nicht sind, ist es nicht so einfach, aus der Bedingungsklausel auszubrechen. Werfen Sie einen Blick auf diese answer.
set -e
kann eine überraschende Sache sein, da es in vielen Fällen ignoriert wird. Verwenden Sie es vorsichtig und beachten Sie diese Fälle.
Ihre Analyse ist nicht korrekt. Wenn 'set -e' in Kraft ist und' run_test1' fehlschlägt, stoppt das Skript hier. Wenn etwas anderes passiert, dann liegt das an einem Teil des Codes, den Sie nicht gezeigt haben. Poste [tatsächlicher Code, der das Problem demonstriert] (https://stackoverflow.com/help/mcve), vorzugsweise vereinfacht, damit Benutzer ihn ohne Makefiles und Docker-Images ausführen können. – Gilles
http://mywiki.wooledge.org/BashFAQ/105 – pynexj