Bitte warten...

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.

Code kopieren
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

Bash kennt keinen Datentyp boolean für Wahrheitswerte und daher auch keine Werte wie true oder false; diese müssen selbst emuliert werden, beispielsweise mit 1 und 0.

Außerdem ist zu beachten, dass Shell-Kommandos in der Regel den Wert 0 zurückgeben, wenn sie fehlerfrei gelaufen sind. Ansonsten geben sie die Nummer des Fehlers zur Identifikation zurück
(Return-Code). Das bedeutet für das Kommando test beispielsweise, dass bei einem wahren Vergleich der Wert 0 zurückgegeben wird und bei einem unwahren der Wert 1. Damit kehren sich die Bedeutungen von 0 (true) und 1 (false) um.

Code kopieren
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 ATyp BBedeutung
-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)

Code kopieren
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:

Code kopieren
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.

Code kopieren
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

Code kopieren
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

Code kopieren
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.

Code kopieren
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.

Code kopieren
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