Was ist die Bedeutung von a ! bevor ein Befehl in der shell?
Die Frage ist im Titel. Was ist der Zweck eines shell-Befehls (Teil der ein shell-Skript), beginnend mit einem Ausrufezeichen? Konkretes Beispiel:
In foo.sh:
#!/usr/bin/env bash
set -e
! docker stop foo
! docker rm -f foo
# ... other stuff
Ich weiß, dass ohne den Raum, das Ausrufezeichen ist für die Geschichte das ersatzstück und die ! <expression>
nach der Mann Seite kann verwendet werden, um zu beurteilen "True, wenn expr falsch ist". Aber in den Beispiel-Kontext, die nicht sinnvoll für mich.
- Wenn der return-code (sichtbar als
$?
) 0 (Erfolg) es klappt es auf 1, wenn der return-code war ein Fehler (nicht-null) es klappt es auf 0 (null). Vielleicht sind diese Befehle sind zu erwarten zu scheitern und haben Sie-e
set oderset -o errexit
? Was auch immer, das ist ein Fall, wo Kommentare sollten Hinzugefügt worden sein. set -e
Befehle ignoriert, deren exit-Status explizit verneint mit!
.
Du musst angemeldet sein, um einen Kommentar abzugeben.
TL;DR: Dies ist nur durch Umgehung der
set -e
- flag in der bestimmten Zeile, wo Sie es verwenden.Hinzufügen hinzufügen hek2mgl die richtige und sinnvolle Antwort.
Haben Sie:
Bash-Referenz-Handbuch → Rohrleitungen beschreibt:
Dies bedeutet, dass
!
vorhergehenden Befehls ist, dass der exit-status:Oder:
Den exit-status ist in vielerlei Hinsicht sinnvoll. In Ihrem Skript, verwendet zusammen mit
set -e
macht das Skript beenden, Wann immer ein Befehl gibt einen nicht-null-status.So, wenn Sie haben:
Wenn
command1
gibt einen nicht-null-status, der script wird beendet und wird nicht gehen zucommand2
.Aber es ist auch ein interessanter Punkt zu erwähnen, beschrieben in 4.3.1 Der Satz Builtin:
Wenn man all diese in Betracht, wenn Sie haben:
Was Sie tun, ist, by-pass das
set -e
- flag in dercommand1
. Warum?command1
richtig läuft, wird es wieder ein null-status.!
negiert wird, aberset -e
wird nicht ausgelöst, eine Ausfahrt durch die, weil Sie von einer Rückkehr status invertiert mit !, wie oben beschrieben.command1
fehlschlägt, wird es wieder einen nicht-null-status.!
negiert wird, so wird die Zeile am Ende der Rückgabe einer null-status, und das Skript wird normal fortgesetzt.set -e
es bedeutet kein Fehler erlaubt in das Skript, aber mit einem führenden!
, markiert es eine Ausnahme Bedeutung dieser Befehl ist in Ordnung, zu scheitern.!
einfach negiert den exit-status eines Befehls. Es ist nur eine der vielen Ausnahmen in der Liste der Befehle, deren exit-statusset -e
ignorieren.!
verneint den exit-status eines Befehls, ob oder nicht die-e
option wirksam ist. Es ist nicht einfach die Marke ein Befehl als eine Ausnahme von der-e
option.set -e
gesetzt ist oder nicht. Aber hier das wesentliche ist über die Nebenwirkung von!
im Rahmen derset -e
, die fehl nicht das Skript selbst, wenn der Befehl erfolgreich ausgeführt wurde. Ohne eine solche Nebenwirkung. das script würde einen Fehler, wenn der exit-status einer gelungen Befehl annulliert!
.Wenn Sie nicht möchten, dass das script fehlschlägt, in beiden Fällen, Fehler oder Erfolg des Befehls, können Sie auch diese alternative:
Den booleschen oder true macht der pipeline haben immer
0
als Rückgabewert.man bash
sagt, , Wenn das reservierte Wort ! vorangestellt ist eine pipeline, die exit-status der pipeline ist die logische negation der exit-status. Würde dies nicht bedeuten, dass, wenn der Befehl erfolgreich ausgeführt wird, würde es einen Fehler auslöst, da es negiert eine Wahre?!
! docker stop foo
.set -e\n! echo "I am okay"\n\echo "done"
läuft durch.set -e\n! give_me_an_error\n\echo "done"
läuft auch durch (das ist, was beschrieben ist in der Antwort). So ist es zumindest in meiner shell (zsh auf macOS) es ist nachsichtig gegen Fehler und beeinträchtigt nicht die erfolgreicheexit 0
Befehle.-e
: Die shell nicht beenden, wenn (...) der Befehl return status wird invertiert mit !.! command
und! command || true
. Das heißt, es ist anzugeben, dass das Ausrufezeichen "statt Mittel fehlschlagen, wenn der Befehl erfolgreich ausgeführt". Ohne Sie, wird der Verweis auf "beiden Fällen" ist auch verwirrend (es war nicht klar, auf meiner ersten Lesung, dass "Fehler oder Erfolg" bedeutete, eine verklärende element und nicht Teil einer Komma-getrennten Liste.set -e
betroffen ist. Es tut invertieren der resultierende Wert von$?
natürlich.