Wie verkette ich Befehle auf der Konsole?

23

In bashmöchte ich manchmal mehrere Befehle hintereinander ausführen und nicht warten, bis sie beendet sind, bevor ich die neuen eingebe. Also mache ich so etwas:

cmd1; cmd2; cmd3

Leider kann einer der Befehle fehlschlagen. In diesem Fall würde ich gerne aufhören. Gibt es eine einfache Möglichkeit, dies zu tun, aber es so zu gestalten, dass ich die Befehle nur weiter ausführe, wenn der vorherige Befehl einen Exit-Code von 0 hat?

pythonische Metapher
quelle
Hier ist eine großartige Antwort von der Unix SE.
NonlinearFruit

Antworten:

39

Verwenden &&Operator,

cmd1 && cmd2 && cmd3

In shellscripting, &&und ||Betreiber nach optimierte Implementierung von logischen Operatoren in C modelliert &&mittels UND - Operator, und ||Mittel OR. Unix ist eng mit C verwandt, und in C wird der zweite Operand von logischen Operatoren nicht ausgewertet, wenn das Ergebnis bereits vom ersten Operanden bekannt ist. ZB "false && x"ist falsefür jede x, so gibt es keine Notwendigkeit zu evaluieren x(insbesondere wenn xes sich um einen Funktionsaufruf handelt); ähnlich für "true || x". Dies wird auch als Kurzschluss Semantik .

Und in Unix ist es üblich, die Rückgabewerte von Befehlen als Wahrheitswerte für "erfolgreiche Fertigstellung" zu interpretieren: Exit-Code 0 bedeutet true(Erfolg), ungleich Null bedeutet false(Misserfolg). Wenn der erste Befehl in cmd1 && cmd2zurückgegeben wird "false"(Exit-Status ungleich Null, was auf einen Fehler hinweist), ist der Status des zusammengesetzten Befehls bekannt: Fehler. Die Gesamtinterpretation von cmd1 && cmd2 kann also lauten: "Ausführen cmd1, UND DANN, wenn es nicht fehlgeschlagen ist cmd2". Welches ist, was Sie im Grunde in Ihrer Frage wollen.

Ähnlich mit OR: cmd1 || cmd2kann interpretiert werden als "Ausführen cmd1, OR WENN es fehlschlägt cmd2".


Protip: Für längere Ketten &&sollten Sie in Betracht ziehen, set -eIhr Skript einzufügen . Es ändert sich im Grunde das Semikolon ;in &&, mit ein paar Sonderfälle.

ulidtko
quelle
1
+1 zum Erklären||
Alp
Können Sie verketten, was auch immer der Status des ersten Befehls ist? (Erfolg oder Misserfolg)
Hugo Trentesaux
@HugoTrentesaux was meinst du? .. Der Erfolg / Misserfolg Ergebnis oder A || Bist genau das gleiche wie die [Kurzschließen] logische A oder B . A || Bist Erfolg , wenn Awar Erfolg , oder wenn Awar Versagen aber Bwar Erfolg ; und A || Bist Versagen , wenn Awar Ausfall und Bwar failure. Ähnlich &&folgt es für logisches UND.
ulidtko
Wie kann ich im Shell-Kontext A und dann B ausführen, unabhängig davon, ob A fehlschlägt oder erfolgreich ist?
Hugo Trentesaux
1
@ HugoTrentesaux das ist, was die normale ;(oder Newline) standardmäßig tut. set -ewird sich ;in &&, grob gesagt. set +e[der Standard] wird A; Bzu dem, was Sie sagen: laufen A, dann egal was laufen B.
ulidtko
13

"Befehle verketten und gruppieren"

ping 192.168.0.1 || { echo "ping not successful"; exit 1; }

Pings führt die verkettete Gruppe von Befehlen in Klammern aus, wenn dies nicht erfolgreich ist.

Beachtung:

Die Liste muss mit einem ";" abgeschlossen werden.

Zwischen Klammern und den gruppierten Befehlen müssen Leerzeichen stehen!

und ich
quelle
6

Einfach mit dem &&Betreiber. Zum Beispiel:

cmd1 && cmd2 && cmd3

Wenn einer der Befehle fehlschlägt (einen anderen Exit-Wert als 0 zurückgibt), werden die anderen Befehle nicht ausgeführt.

Wuffers
quelle