Operatoren
Hinweis:
"Verbundene Befehle" bedeutet, dass mehrere Befehle bzw. deren Ausführung miteinander verbunden werden. Der Ein- bzw. Ausgabekanal ist aber nicht über einen Pipe-Operator mit einem anderen Ein- bzw. Ausgabekanal verbunden. D.h. die Eingabe erfolgt für alle Befehle über die Standardeingabe (in der Regel die Tastatur) und die Ausgabe über die Standardausgabe (in der Regel den Bildschirm). Für verbundene Befehle ist natürlich trotzdem die Umleitung von Daten möglich, z.B. in eine Datei. Die Bash kennt vier verschiedene Arten von verbundenen Befehlen.
Verbinden von Befehlen ohne Bedingung mit ;¶
Mit Hilfe des Semikolons ; lassen sich mehrere Befehle verbinden, die dann nacheinander ausgeführt werden, z.B.
ls /home/user ; ls /home/user/Desktop
Zuerst wird das Verzeichnis home/user ausgegeben, dann das Verzeichnis home/user/Desktop. Die Ausgaben schließen unmittelbar aneinander an, es erfolgt keine (optische) Trennung. ⚓︎
UND-Verknüpfung von Befehlen mit &&¶
Mit Hilfe von zwei Kaufmanns-Und && wird eine kurzschließende UND-Verknüpfung zwischen Befehlen erstellt. Dies bedeutet, dass der zweite Befehl nur ausgeführt wird, wenn der erste Befehl erfolgreich (fehlerfrei) ausgeführt wurde. Eine "klassische" Anwendung ist:
apt-get update && apt-get dist-upgrade
Im zweiten Beispiel wird zuerst ein Verzeichnis angelegt, dann der USB-Stick /dev/sda dorthin eingebunden und anschließend das Verzeichnis ausgelesen. mount hätte keinen Sinn, wenn das Mount-Verzeichnis nicht existieren würde, ls hätte keinen Sinn, wenn das Geräte nicht eingehängt wäre:
mkdir /media/usbstick && mount -t auto -o rw /dev/sda /media/usbstick && ls /media/usbstick
Aus der Logik ist klar, dass eine Aussage, die aus zwei Teilaussagen besteht, nur wahr ist, wenn beide Teilaussagen wahr sind. Daher wird die Auswertung abgebrochen, wenn ein Teil (der erste) falsch ist, denn dann kann der Gesamtausdruck nicht mehr richtig werden.
ODER-Verknüpfung von Befehlen mit ||¶
Mit Hilfe von zwei Pipe-Zeichen || wird eine kurzschließende ODER-Verknüpfung von Befehlen erzeugt. Dies bedeutet, dass der zweite Befehl nur ausgeführt wird, wenn der erste Befehl nicht erfolgreich (fehlerfrei) beendet wurde. || ist also das Gegenteil zu &&. Ein Beispiel:
mount /cdrom || eject /cdrom
Es wird versucht, CD-Rom einzuhängen. Schlägt dies Fehl (weil z.B. keine CD eingelegt ist), dann öffnet sich die Schublade des Laufwerks.
Auch hier steckt die gleiche Logik dahinter: Eine oder-kombinierte Aussage, deren erste Teilaussage wahr ist, ist insgesamt wahr, auch wenn der zweite Teil falsch wäre. Daher wird der zweite Teil nicht ausgewertet, wenn der erst wahr war.
Im ganzen Satz:
1 | (($RANDOM % 2 == 0)) && echo "Null" || echo "nicht Null" |
Ist die Zufallszahl, die entweder 1 oder 0 ist (% ist der Modulo, der Rest der Division) 0, dann wird auch "Null" ausgegeben. echo liefert, da es eigentlich nicht schiefgehen kann, selbst WAHR zurück, so dass der Oder-Teil nicht ausgeführt wird. Außer die Zahl war nicht 0, dann wird auch die &&-Verknüpfung nicht wahr ergeben, und dann wird der oder-Teil ausgeführt, der "nicht Null" ausgibt, selbst aber wieder WAHR im Endergebnis liefert.
Ein Befehl im Hintergrund mit &¶
Mit Hilfe des Kaufmanns-Und & wird der erste Befehl im Hintergrund ausgeführt, alle anderen Befehle werden im Vordergrund ausgeführt. Die Ausgabe der Befehle mischt sich unter Umständen in der Ausgabe, da beide Befehle gleichzeitig ausgeführt werden. Das gleichzeitige Ausführen von zwei Befehlen (im Terminal) hat dann Sinn, wenn beide Befehle eine längere Ausführungszeit haben. Der allgemeine Syntax lautet:
Befehl1 & Befehl2
Eine recht nützliche Anwendung von & ist der Aufruf zweier gleichzeitig benötigter Programme, hier im Beispiel ein Terminal und ein Editor:
xterm & xemacs
Kombinieren von Bedingungen¶
Es lassen sich alle oben beschriebenen Bedingungen kombinieren. && und || habe die gleiche Priorität, ebenso ; und &. Allerdings ist die Priorität von && und || höher als die von ; und &. Beispiel:
Befehl1 && Befehl2 ; Befehl3
Das heißt: Führe Befehl2 nur aus, wenn Befehl1 erfolgreich war. Unabhängig davon führe abschließend Befehl3 aus.
Klammern¶
Klammern dienen dazu, die Priorität von Operatoren zu überschreiben. Eine geklammerte Liste von Befehlen gilt syntaktisch auf der nächstäußeren Ebene als ein Befehl.
Die Shell unterstützt zwei Arten von Klammern:
( Befehl1 ; Befehl2 && ... ): Zur Ausführung der enthaltenen Befehle wird eine eigene, untergeordnete Shell gestartet.
{ Befehl1 || Befehl2 ; ...; }: Führt Befehle im Kontext derselben Shells aus, es wird keine eigene Shell gestartet.
Das abschließende Semikolon ist bei der Verwendung der Geschweiften zwingend. In Skripten kann stattdessen die schließende Klammer in einer neuen Zeile stehen.
Befehl1 && { Befehl2 ; Befehl3; }
Ist Befehl1 erfolgreich, führe auch Befehl2 gefolgt von Befehl3 aus, andernfalls weder noch.