TL; DR: Hiermit wird nur das set -e
Flag in der Zeile umgangen, in der Sie es verwenden.
Hinzufügen von add zu hek2mgls korrekter und nützlicher Antwort .
Du hast:
set -e
! command
Bash Referenzhandbuch → Pipelines beschreibt:
Jeder Befehl in einer Pipeline wird in einer eigenen Subshell ausgeführt. Der Exit-Status einer Pipeline ist der Exit-Status des letzten Befehls in der Pipeline (...). Wenn das reservierte Wort '!' Vor der Pipeline ist der Exit-Status die logische Negation des Exit-Status, wie oben beschrieben. Die Shell wartet, bis alle Befehle in der Pipeline beendet sind, bevor ein Wert zurückgegeben wird.
Dies bedeutet, dass das !
Voranstellen eines Befehls dessen Beendigungsstatus negiert:
$ echo 23
23
$ echo $?
0
$ ! echo 23
23
$ echo $?
1
Oder:
$ echo 23 && echo "true" || echo "fail"
23
true
$ ! echo 23 && echo "true" || echo "fail"
23
fail
Der Exit-Status ist in vielerlei Hinsicht nützlich. In Ihrem Skript set -e
wird das Skript zusammen mit verwendet, wenn ein Befehl einen Status ungleich Null zurückgibt.
Also, wenn Sie haben:
set -e
command1
command2
Wenn command1
ein Status ungleich Null zurückgegeben wird, wird das Skript beendet und nicht fortgesetzt command2
.
Es gibt jedoch auch einen interessanten Punkt zu erwähnen, der in 4.3.1 The Set Builtin beschrieben wird :
-e
Beenden Sie das Programm sofort, wenn eine Pipeline (siehe Pipelines), die aus einem einzelnen einfachen Befehl (siehe Einfache Befehle), einer Liste (siehe Listen) oder einem zusammengesetzten Befehl (siehe Zusammengesetzte Befehle) bestehen kann, einen Status ungleich Null zurückgibt. Die Shell wird nicht beendet, wenn der fehlgeschlagene Befehl unmittelbar nach einer Weile oder bis zum Schlüsselwort Teil der Befehlsliste ist, Teil des Tests in einer if-Anweisung, Teil eines Befehls, der in einem && oder || ausgeführt wird Liste mit Ausnahme des Befehls nach dem letzten && oder ||, eines Befehls in einer Pipeline außer dem letzten oder wenn der Rückgabestatus des Befehls mit invertiert wird! . Wenn ein anderer zusammengesetzter Befehl als eine Subshell einen Status ungleich Null zurückgibt, weil ein Befehl fehlgeschlagen ist, während -e ignoriert wurde, wird die Shell nicht beendet. Ein Trap auf ERR wird, falls gesetzt, ausgeführt, bevor die Shell beendet wird.
Berücksichtigen Sie all dies, wenn Sie:
set -e
! command1
command2
Was Sie tun, ist, die set -e
Flagge in der zu umgehen command1
. Warum?
- Wenn es
command1
ordnungsgemäß ausgeführt wird, wird der Status Null zurückgegeben. !
wird es negieren, aber set -e
keinen Exit durch das auslösen, da es von einem mit! invertierten Rückgabestatus stammt, wie oben beschrieben.
- Wenn dies
command1
fehlschlägt, wird ein Status ungleich Null zurückgegeben. !
wird es negieren, so dass die Zeile am Ende einen Nullstatus zurückgibt und das Skript normal fortgesetzt wird.
$?
) 0 (Erfolg) war, wird er auf 1 umgedreht. Wenn der Rückgabecode ein Fehler war (nicht Null), wird er auf 0 (Null) umgedreht. Vielleicht wird erwartet, dass diese Befehle fehlschlagen und Sie haben-e
oder gesetztset -o errexit
? Wie auch immer, dies ist ein Fall, in dem Kommentare hätten hinzugefügt werden müssen.