Bash: Bedingungen und Vergleiche
Mit der Prüfung von Bedingungen lassen sich, wie in anderen Programmiersprachen auch, Verzweigungen im Ablauf eines Bash-Skriptes erzeugen. Die Prüfung von Bedingungen wird mit dem Schlüsselwort if (falls) eingeleitet. Darauf folgt die zu prüfende Bedingung in Klammern sowie das Schlüsselwort then (dann). Alle folgenden Kommandos werden ausgeführt, wenn die Prüfung der Bedingung true (wahr) ergibt.
Optional können weitere Verzweigungen durch die Prüfung weiterer Bedingungen angehängt werden, die mit dem Schlüsselwort elif (else if) eingeleitet werden. Außerdem kann mit dem Schlusselwort else (ansonsten) eine Verzweigung angegeben werden, die ausgeführt wird, wenn alle zu prüfenden Bedingungen false (falsch) ergeben haben.
Schließlich muss der if-Block mit dem Schlüsselwort fi (if rückwärts buchstabiert) beendet werden.
value=125
if (($value < 0)); then
echo $value "ist kleiner als 0."
elif (($value > 0)); then
echo $value "ist größer als 0."
else
echo $value "ist gleich 0."
fi
test 1 -lt 2
echo $? # 0 (true)
test 1 -gt 2
echo $? # 1 (false)
Vergleichsoperatoren
Für den Vergleich innerhalb von Bedingungen existieren verschiedene Arten von Operatoren, die von der Art der Klammerung abhängen.
Zunächst einmal aber eine Übersicht der Operatoren:
Typ A | Typ B | Bedeutung |
---|---|---|
-eq | == | ist gleich |
-ne | != | ist ungleich |
-lt | < | ist kleiner als |
-le | <= | ist kleiner als oder gleich |
-gt | > | ist größer als |
-ge | >= | ist größer als oder gleich |
-a | && | logisches UND |
-o | || | logisches ODER |
Für den Musterabgleich mit Regulären Ausdrücken existieren darüber hinaus auch noch die Operatoren =~ (Übereinstimmung) und !~ (keine Übereinstimmung), die hier aber nicht weiter behandelt werden.
Einfache eckige Klammern
Zwischen Klammern und Bedingung muss ein Leerzeichen Abstand sein.
Die Operatoren <= und >= können nicht verwendet werden.
Die Operatoren < und > müssen mit \ escapet werden.
Logische Operatoren müssen innerhalb von Klammern vom Typ A und außerhalb vom Typ B sein.
Numerische Vergleiche (Zahlen): Typ A und Typ B
Alphanumerische Vergleiche (Strings): nur Typ B (= und == sind gleichwertig)
if [ $a \> $b -o $a == $b ]; then echo "$a >= $b"; fi
if [ $a \> $b ] || [ $a == $b ]; then echo "$a >= $b"; fi
Statt einfacher eckiger Klammern kann auch das Kommando test verwendet werden:
if test $a \> $b -o $a == $b; then echo "$a >= $b"; fi
if test $a \> $b || test $a == $b; then echo "$a >= $b"; fi
Das Kommando test kennt unter anderem noch die Optionen -n und -z, mit denen geprüft werden kann, ob eine Variable einen Inhalt hat oder nicht.
Die Option -n (nonzero) gibt true zurück, wenn die Länge einer Variable ungleich 0 ist.
Die Option -z (zero) gibt true zurück, wenn die Länge einer Variable gleich 0 ist.
a=""
if test -n "$a"; then echo "nicht leer"; else echo "leer"; fi # leer
if test -z "$a"; then echo "leer"; else echo "nicht leer"; fi # leer
a=hallo
if test -n "$a"; then echo "nicht leer"; else echo "leer"; fi # nicht leer
if test -z "$a"; then echo "leer"; else echo "nicht leer"; fi # nicht leer
Doppelte eckige Klammern
Zwischen Klammern und Bedingung muss ein Leerzeichen Abstand sein.
Die Operatoren <= und >= können nicht verwendet werden.
Numerische Vergleiche (Zahlen): Typ A und Typ B
Alphanumerische Vergleiche (Strings): nur Typ B
if [[ $a -gt $b -o $a -eq $b ]]; then echo "$a >= $b"; fi
if [[ $a > $b || $a == $b ]]; then echo "$a >= $b"; fi
Doppelte runde Klammern
Numerische Vergleiche (Zahlen): nur Typ B
Alphanumerische Vergleiche (Strings): nicht möglich
Das $-Zeichen vor einer Variable kann weggelassen werden.
if (($a > $b || a == b)); then echo "$a >= $b"; fi
Ternärer Operator
Der ternäre Operator ist eine Kurzschreibweise für einen einfachen if/else-Vergleich. Er besteht aus drei Teilen: der zu prüfenden Bedingung, dem Resultat bei true und dem Resultat bei false.
read -p "Zahl: " a
(($a < 1000)) && check="okay" || check="zu groß"
# entspricht: if (($a < 1000)); then check="okay"; else check="zu groß"; fi
echo $check
Fallunterscheidung
Verzweigungen, die von verschiedenen Zuständen lediglich einer einzigen Variable abhängen, können mit der case-Anweisung realisiert werden. Die einzelnen Verzweigungen werden von dem Wert der zu prüfenden Variable eingeleitet (bei mehreren möglichen Werten durch das |-Zeichen getrennt), gefolgt von einem )-Zeichen. Anschließend folgt eine Liste der Anweisungen, die für den Fall ausgeführt werden sollen, wenn die Variable einen der genannten Werte besitzt. Jede dieser Listen wird mit zwei Semikolons ;; beendet. Optional kann man noch eine Liste mit Anweisungen angeben, die ausgeführt werden, falls die Variable keinen der möglichen Werte angenommen hat; dies erfolgt durch den Platzhalter * (Zeile 17 bis 19). Der case-Block wird schließlich mit der Anweisung esac (case rückwärts geschrieben) beendet.
echo "Eiscafé Bash hat Schoko, Erdbeer, Vanille und Haselnuss."
read -p "Welches Eis möchtest du? " eissorte
case $eissorte in
Schoko | Haselnuss)
preis=110
typ=0
;;
Vanille)
preis=120
typ=0
;;
Erdbeer)
preis=100
typ=1
;;
*)
preis=0
;;
esac
verpackungen=("in der Waffel" "im Becher")
if ((preis != 0)); then
echo $eissorte kostet $preis ct pro Kugel und gibt es ${verpackungen[typ]}.
else
echo $eissorte haben wir nicht im Angebot.
fi