Durch die Kontrolloperatoren ¦ ¦¦ & && ; ;; ( ) können in der bash mehrere Kommandos miteinander verkettet werden. Eine solche Verkettung von Kommandos nennt man Liste. Dazu gibt es verschiedenen Möglichkeiten.
In der bash können mehrere Kommandos in einer Liste durch Semikolon getrennt werden.
Die bash wird dann die Kommandos nacheinander von links nach rechts ausführen und der exit-status entspricht dem exit-status des letzten Kommandos.
Kommando1; Kommando2; Kommando3
Mehrere Kommandos werden durch logische UND-Verknüpfung miteinander verbunden.
Kommando1 && Kommando2
Kommando2 wird dann nur ausgeführt, wenn Kommando1 mit dem exit-status 0 (Null wahr, true) beendet wurde.
Das bedeutet im Allgemeinen, dass Kommando1 ohne Fehler beendet wurde.
Es können auch mehr als zwei Kommandos miteinander verkettet werden.
Mehrere Kommandos werden durch logische ODER-Verknüpfung miteinander verbunden.
Kommando1 ¦¦ Kommando2
Kommando2 wird dann nur ausgeführt, wenn Kommando1 mit dem exit-status ungleich 0 (falsch, false) beendet wurde.
Das bedeutet im Allgemeinen, dass Kommando1 mit einer Fehlermeldung abgebrochen wurde.
Es können auch mehr als zwei Kommandos miteinander verkettet werden.
Mit geschweiften Klammern können Listen gruppiert werden.
Eine solche gruppierte Liste wird ebenfalls in der Shell ausgeführt und wirkt als ein Kommandoaufruf.
Geschweifte Klammern können zB. eingesetzt werden, um Vorränge bei Kombinationen von UND- und ODER-Verkettungen zu regeln, da beide Verkettungen den gleichen Rang besitzen.
zB.
Kommando1 ¦¦ Kommando2 && Kommando3
ist gleichbedeutend mit
{ Kommando1 ¦¦ Kommando2;} && Kommando3
, dh. Kommando3 wird nur ausgeführt, wenn Kommando1 mit dem exit-status 0 (Null, wahr, true) endet oder Kommando1 mit dem exit-status 1 (falsch, false) endet, aber Kommando2 mit 0 (true).
Liefern Kommando1 und Kommando2 ein false, dann wird auch Kommando3 nicht ausgeführt.
Lautet der Aufruf jedoch
Kommando1 ¦¦ { Kommando2 && Kommando3 }
, dann wird Kommando2 ausgeführt, wenn Kommando1 mit false endet und wenn Kommando2 mit true endet, dann wird auch Kommando3 ausgeführt.
Eine weitere wichtige Anwendung der Gruppierung findet man in Shellfunktionen.
Mehrere Kommandos werden durch Pipes ¦ miteinander verbunden.
Kommando1 ¦ Kommando2
Dabei wird die Ausgabe des Kommandos1 auf stdout an die Eingabe von Kommando2 an stdin gesendet und kann von diesem Kommando weiter verarbeitet werden.
Wenn das letzte Kommando abgeschlossen ist, wird dessen exit-status als exit-status der Liste zurückgegeben.
Es können auch mehr als zwei Kommandos miteinander verkettet werden.
Achtung! Die Kommandos in der Pipe (Kommando2 und folgende) werden in einer Subshell ausgeführt.
Diese erbt die Arbeitsumgebung von der aufrufenden Shell (in der das Kommando vor der Pipe läuft) und führt das Kommando aus.
Nach der Ausführung geht die Arbeitsumgebung der Subshell verloren.
Das bedeutet, dass alle Veränderungen z.B. von Variablen verloren gehen und in der aufrufenden Shell nicht mehr existieren.
Beispiel:
Nehmen wir an, in einem Script befindet sich folgendes Konstrukt:
Kommando1
Kommando2 ¦ Kommando3 ¦ Kommando4
Kommando5
Die Kommandos1, 2 und 5 werden in der selben Shell ausgeführt, das bedeutet, dass alle Änderungen der Umgebung (z.B. schreiben in Variablen) die Kommando1 vornimmt auch von Kommando2 und 5 gelesen werden können und alle Änderungen von Kommando2 dem Kommando5 zugänglich sind.
Nach der Ausführung von Kommando2 wird das Kommando3 in einer Subshell gestartet, die die Arbeitsumgebung von Kommando2 übernimmt (kopiert).
Kommando3 kann also auf alle Veränderungen der Arbeitsumgebung durch Kommando1 und 2 zugreifen.
Alle Änderungen der Arbeitsumgebung durch Kommando3 haben nur Auswirkungen auf seine eigene Kopie der Arbeitsumgebung der Subshell und wirken nicht auf die Arbeitsumgebung der Kommandos1, 2 und 5, da diese in der aufrufenden (parent)-Shell ausgeführt werden.
Nach der Ausführung von Kommando3 wird Kommando4 ebenfalls in einer Subshell ausgeführt, die die Arbeitsumgebung der Subshell von Kommando3 erbt.
Deshalb kann Kommando4 auf alle Änderungen der Arbeitsumgebung durch Kommando1, 2 und 3 zugreifen.
Nach Ausführung des Kommandos4 wird die Subshell beendet und die Arbeitsumgebung dieser Subshell geht verloren.
Deshalb kann Kommando5 nicht auf Änderungen der Arbeitsumgebung der Kommandos3 und 4 zugreifen, sie sind mit dem Beenden der Subshell verloren gegangen.
Duch Einklammerung einer Liste in runden Klammern werden die Kommandos der Liste in einer Subshell ausgeführt.
Alle Variableninhalte, die innerhalb der Liste benutzt werden gehen nach Beendigung der Subshell verloren.
Subshells können z.B. sehr effizient eingesetzt werden, wenn alle Kommandos in der Liste gemeinsame Ein- und Ausgabeumlenkungen benutzen sollen.