Unter Kontrollstrukturen versteht man allgemein Sprachkonstrukte – sagen wir einfach einmal Befehle –, mit denen sich die Ausführung von Programmteilen steuern lässt. Die wohl bekannteste Kontrollstruktur ist if, die Prüfung einer Bedingung. Sie hat in der Bash die Form:
if Bedingung1; thenWenn Bedingung 1 wahr elif Bedingung2; thenWenn Bedingung 2 wahr elif Bedingung3; thenWenn Bedingung 3 wahr elseWenn Bedingung 1 bis 3 falsch fi
Die Konstruktion beginnt stets mit dem Schlüsselwort if und endet mit fi, dem umgedrehten "if". Das Konzept des if-Konstrukts ist modular: Was nicht gebraucht wird, kann entfallen. Wenn Sie also nur sagen wollen, dass die Variablen A und B das gleiche enthalten, können Sie schreiben:
if [ $A = $B ]; then echo "A und B sind gleich." fi
Wenn Sie im Falle eines Unterschieds dies ebenfalls vermelden wollen, kommt zusätzlich else ins Spiel:
if [ $A = $B ]; then echo "A und B sind gleich." else echo "A und B sind ungleich." fi
Im letzten Beispiel hatten wir zwei Anweisungsblöcke, den if-Block und den else-Block, mit je einer echo-Anweisung. Diese Blöcke können auch mehrere Befehle enthalten:
if [ $A = $B ]; then echo "A und B sind gleich." echo "Wer hätte das gedacht?" else echo "A und B sind ungleich." echo "Schade eigentlich." fi
Die beiden Blöcke reichen vom Schlüsselwort then beziehungsweise else bis zum nächsten Schlüsselwort des if-Konstrukts. Dabei sind auch Verschachtelungen möglich:
if [ $A = $B ]; then
echo "A und B sind gleich."
if [ $A = "0" ]; then
echo "A und B sind null."
fi
else
echo "A und B sind ungleich."
fi
In diesem Fall wird das innere if-Konstrukt als eine einzige Anweisung betrachtet und könnte wiederum weitere if-Konstrukte enthalten.
Bedingung
if kann nur zwei Zustände unterscheiden: Wahr oder falsch, wobei 0 als wahr und alles andere als falsch gewertet wird. Die Bedingung wird dabei als Programmaufruf aufgefasst:
if echo "Hallo Welt"; then echo "OK" fi
Die Bedingung im letzten Beispiel ist echo "Hallo Welt" – und obwohl wir keinerlei Vergleich haben, scheint die Bedingung wahr zu sein, denn es wird anschließend OK ausgegeben. Das Ergebnis des echo-Aufrufs muss 0 gewesen sein. Das können Sie mit der Spezial-Variablen $? überprüfen, die wir in Teil 2 (Ausgabe 01/2001) angerissen haben:
echo "Hallo Welt" Hallo Weltecho $? 0
$? liefert Ihnen den Rückgabewert (Exit-Status), den jedes Programm beim Beenden an das Betriebssystem zurückgeben muss. Unter den Programmierern hat sich eingebürgert, bei normalem Programmablauf stellvertretend 0 zurückzugeben, im Fehlerfall dann einen anderen Wert. Es gibt allerdings auch einzelne Programme, die nur negative Werte für aufgetretene Fehler liefern. Informationen, welcher Wert was bedeutet, findet man manchmal in der Dokumentation oder Manual-Page.
Anwender benötigen den Rückgabewert normalerweise nicht, wohl aber Skripte. In der Praxis kommt man nicht immer mit dem Sprachumfang der Bash aus, man bedient sich externer Programme wie cp, cat oder grep, um einzelne Aufgaben zu lösen. Mit dem Exit-Status kann das Bash-Skript sehr leicht entscheiden, ob bei einem der Kommandos ein Fehler aufgetreten ist oder nicht – und das, ohne die Bildschirmausgabe auswerten oder den Anwender fragen zu müssen.
Als Beispiel verwenden wir das Filter-Programm grep. Damit kann man Dateien nach dem Vorkommen von Wörtern und anderen Zeichenfolgen durchsuchen. Normal gibt grep das Ergebnis direkt auf dem Bildschirm aus, mit der Option -q im folgenden Listing unterdrücken wir das jedoch. Wir lassen die Datei /etc/passwd nach dem nicht existenten Benutzer tux durchsuchen:
if grep -q tux /etc/passwd; then echo "Hallo Tux." else echo "Tux kenne ich nicht." fi
Das Ergebnis ist "Tux kenne ich nicht." Mit dem als root aufzurufenden Befehl useradd tux können Sie nun den Benutzer tux anlegen – keine Sorge, es kann sich niemand als Tux einloggen. Unser Beispiel liefert nun "Hallo Tux." Mit userdel tux löschen Sie Tux später wieder.
Wir haben ausgenutzt, dass grep im Erfolgsfall, wenn es die Zeichenkette "tux" finden konnte, 0 zurückgibt, während der Rückgabewert bei Misserfolg 1 ist.
Mehrzeilige Bedingungen
Die Länge der Bedingung ist nicht beschränkt, sie kann mehrere Programmaufrufe umfassen. Bewertet wird dabei stets der Rückgabewert des letzten Kommandos. Zur besseren Lesbarkeit benutzt man für mehrzeilige Bedingungen eine etwas andere Schreibweise des if-Konstrukts:
01 if 02 echo "Suche:" 03 echo " tux" 04 echo "in" 05 echo "/etc/passwd." 06 grep -q tux /etc/passwd; 07 then 08 echo "Hallo Tux." 09 else 10 echo "Tux kenne ich nicht." 11 fi
Wichtig ist das Semikolon hinter der letzten Anweisung im Bedingungs-Teil, ohne das das Schlüsselwort then nicht erkannt würde. Der Einsatz mehrzeiliger Bedingungs-Blöcke ist jedoch die Ausnahme und nur selten sinnvoll.



