Aufzucht und Hege von Shell-Scripts: Wahr und Falsch

Was ist wahr, was ist falsch?

Über den Returncode von Programmen habe ich schon oben in Fehler geplaudert. Diese Unterscheidung (0 = OK, ungleich 0 = Fehler) gilt aber auch beim Evaluieren von Ausdrücken: 0 = Wahr, ungleich 0 = Falsch. Das Shell-Builtin test macht auch nichts anderes: Es liefert 0 als Returncode, wenn der zu testende Ausdruck wahr ist, ansonsten 1. Probiert es aus:

  jan@jack:~/tmp> test 1 -eq 1
  jan@jack:~/tmp> echo $?
  0
  jan@jack:~/tmp> test 1 -eq 2
  jan@jack:~/tmp> echo $?
  1

Es ist also problemlos möglich, den Returncode jedes Programms z. B. in if-Abfragen oder als Abbruchbedingung in Schleifen direkt zu nutzen, diese Kontrollstrukturen werten nämlich auch nur aus, ob ihr Argument 0 oder nicht 0 ist. Oft sieht man hier unnötig komplizierte Konstruktionen, die man deutlich einfacher formulieren könnte:

  # pruefen, ob ein bestimmtes Suchmuster in einer Datei enthalten ist
  # unschoen
  if test `grep Suchmuster Datei | wc -l` -gt 0; then
    ...
  fi
  # einfacher
  if grep -q Suchmuster Datei; then
    ...
  fi

  # Schleife, solange noch .bak-Dateien vorhanden sind
  # unschoen
  while true; do
    anz_bak_files=`ls *.bak 2>/dev/null | wc -l`
    test $anz_bak_files -eq 0 && break
    ...
  done
  # einfacher
  while ls *.bak >/dev/null 2>>&1; do
    ...
  done

Übrigens, das in der while-Schleife genutzte true ist ein Shell-Builtin, das einfach immer 0 als Returnwert liefert, sein Gegenpart ist - genau - false.

Einen hab ich noch: Ihr habt in den Beispielen ab und zu mal solche Konstruktionen gesehen:
Befehl1 && Befehl2 oder
Befehl1 || Befehl2
Das sind in Wirklichkeit einfach UND- bzw. ODER-Bedingungen. Die o. g. Befehlsverknüpfungen machen sich zu Nutze, dass die Shell genaus so faul ist wie die meisten Programmierer:

Damit ist auch klar, dass man den Returncode der gesamten Verknüpfung mit Vorsicht betrachten muss, er ist nämlich nicht in jedem Fall eindeutig: Nur wenn die UND-Bedingung Wahr (also 0) ist, dann ist klar, dass beide Kommandos erfolgreich waren. Ist sie Falsch, dann ist nur klar, dass eines der beiden Kommandos einen Fehler lieferte, welches, das ist nicht zu ermitteln. Für die ODER-Bedingung ist es genau anders rum: Nur wenn sie Falsch (also ungleich 0) liefert, dann ist klar, dass beide Kommandos einen Fehler lieferten, wenn sie Wahr (also 0) liefert, dann ist eines der Kommandos erfolgreich gewesen, welches, das ist nicht definiert.