Rheinwerk Computing < openbook > Rheinwerk Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

 << zurück
Shell-Programmierung von Jürgen Wolf
Einführung, Praxis, Referenz
Buch: Shell-Programmierung

Shell-Programmierung
782 S., mit CD, 44,90 Euro
Rheinwerk Computing
ISBN 3-89842-683-1
gp Kapitel 4 Kontrollstrukturen
  gp 4.1 Bedingte Anweisung mit if
    gp 4.1.1 Kommandos testen mit if
    gp 4.1.2 Kommandoverkettung über Pipes mit if
  gp 4.2 Die else-Alternative für eine if-Verzweigung
  gp 4.3 Mehrfache Alternative mit elif
  gp 4.4 Das Kommando test
    gp 4.4.1 Ganze Zahlen vergleichen
    gp 4.4.2 Ganze Zahlen vergleichen mit let (Bash und Korn-Shell only)
    gp 4.4.3 Zeichenketten vergleichen
    gp 4.4.4 Zeichenketten vergleichen (Bash und Korn-Shell only)
  gp 4.5 Status von Dateien erfragen
  gp 4.6 Logische Verknüpfung von Ausdrücken
    gp 4.6.1 Negationsoperator !
    gp 4.6.2 Die UND-Verknüpfung (-a und &&)
    gp 4.6.3 Die ODER-Verknüpfung (-o und ||)
    gp 4.6.4 Klammerung und mehrere logische Verknüpfungen
  gp 4.7 Short Circuit-Tests – ergebnisabhängige Befehlsausführung
  gp 4.8 Die Anweisung case
    gp 4.8.1 Alternative Vergleichsmuster
    gp 4.8.2 case und Wildcards
    gp 4.8.3 case und Optionen
  gp 4.9 Schleifen
  gp 4.10 for-Schleife
    gp 4.10.1 Argumente bearbeiten mit for
    gp 4.10.2 for und die Dateinamen-Substitution
    gp 4.10.3 for und die Kommando-Substitution
    gp 4.10.4 for und Array (Bash und Korn Shell only)
    gp 4.10.5 for-Schleife mit Schleifenzähler (Bash only)
  gp 4.11 Die while-Schleife
  gp 4.12 Die until-Schleife
  gp 4.13 Kontrollierte Sprünge
    gp 4.13.1 Der Befehl continue
    gp 4.13.2 Der Befehl break
  gp 4.14 Endlosschleifen


Rheinwerk Computing

4.8 Die Anweisung casdowntop

Die Anweisung case wird oft als Alternative zu mehreren if–elif-Verzweigungen verwendet. Allerdings überprüft case im Gegensatz zu if oder elif nicht den Rückgabewert eines Kommandos. case vergleicht einen bestimmten Wert mit einer Liste von anderen Werten. Findet hierbei eine Übereinstimmung statt, können einzelne oder mehrere Kommandos ausgeführt werden. Außerdem bietet eine case-Abfrage im Gegensatz zu einer if–elif-Abfrage erheblich mehr Übersicht (siehe Abbildung 4.10). Hier die Syntax, wie Sie eine Fallunterscheidung mit case formulieren:

case "$var" in
   muster1)   kommando
              ...
              kommando ;;
   muster2)   kommando
              ...
              kommando ;;
   mustern)   kommando
              ...
              kommando ;;
esac

Abbildung
Hier klicken, um das Bild zu Vergrößern

Abbildung 4.10   Die case-Anweisung


Die Zeichenkette »var« nach dem Schlüsselwort case wird nun von oben nach unten mit den verschiedensten Mustern verglichen, bis ein Muster gefunden wurde, das auf »var« passt oder eben nicht. In der Syntaxbeschreibung wird bspw. zuerst »muster1« mit »var« verglichen. Stimmt »muster1« mit »var« überein, werden entsprechende Kommandos ausgeführt, die sich hinter dem betroffenen Muster befinden. Stimmt »var« nicht mit »muster1« überein, wird das nächste Muster »muster2« mit »var« verglichen. Dies geht so lange weiter, bis eine entsprechende Übereinstimmung gefunden wird. Wird keine Übereinstimmung gefunden, werden alle Befehle der case-Anweisung ignoriert und die Ausführung hinter esac fortgeführt.

Eine sehr wichtige Rolle spielen auch die doppelten Semikolons (;;). Denn stimmt ein Muster mit »var« überein, werden die entsprechenden Befehle dahinter bis zu diesen doppelten Semikolons ausgeführt. Wenn die Shell auf diese Semikolons stößt, wird aus der case-Verzweigung herausgesprungen (oder der Muster-Befehlsblock beendet) und hinter esac mit der Scriptausführung fortgefahren. Würden hier keine doppelten Semikolons stehen, so würde die Shell weiter fortfahren (von oben nach unten), Muster zu testen. Ebenfalls von Bedeutung: Jedes Muster wird mit einer runden Klammer abgeschlossen, um es von den folgenden Kommandos abzugrenzen. Es darf aber auch das Muster zwischen zwei Klammern ( muster ) gesetzt werden. Dies verhindert, dass bei Verwendung von case in einer Kommando-Substitution ein Syntaxfehler auftritt. Abgeschlossen wird die ganze case-Anweisung mit esac (case rückwärts geschrieben).

Das Muster selbst kann ein String sein oder eines der bereits bekannten Metazeichen *, ? oder [ ]. Ebenso können Sie eine Muster-Alternative wie *(...|...|...); @(...|...|...) usw. der Bash und der Korn-Shell aus Abschnitt 1.10.8 einsetzen. Sollten Sie diese Sonderzeichen in Ihren Mustern setzen, so dürfen die Muster nicht zwischen Anführungszeichen stehen.

Der Wert von »var« muss nicht zwangsläufig eine Zeichenkette, sondern kann auch ein Ausdruck sein, der eine Zeichenkette zurückliefert. Es empfiehlt sich allerdings immer, »var« zwischen Double Quotes einzuschließen, um eventuell einen Syntaxfehler bei leeren oder nicht gesetzten Variablen zu vermeiden.

Ein simples Beispiel:

# Demonstriert die case-Anweisung
# acase1
tag=`date +%a`
case "$tag" in
  Mo)   echo "Mo : Backup Datenbank machen" ;;
  Di)   echo "Di : Backup Rechner Saurus"   ;;
  Mi)   echo "Mi : Backup Rechner Home"     ;;
  Do)   echo "Do : Backup Datenbank machen" ;;
  Fr)   echo "Fr : Backup Rechner Saurus"   ;;
  Sa)   echo "Sa : Backup Rechner Home"     ;;
  So)   echo "So : Sämtliche Backups auf CD-R sichern" ;;
esac

Im Beispiel wurde mit einer Kommando-Substitution der aktuelle Tag an die Variable tag übergeben. Anschließend wird in der case-Anweisung entsprechender Tag ausgewertet und ausgegeben. Hängen Sie jetzt hierbei statt einer simplen Ausgabe einige sinnvolle Befehle an und lassen jeden Tag den cron-Daemon darüber laufen, haben Sie ein echtes Backup-Script, das Ihnen Woche für Woche die ganze Arbeit abnimmt. Natürlich muss dies nicht unbedingt ein Backup-Script sein, es können auch bestimmte Log-Dateien ausgewertet werden.


Rheinwerk Computing

4.8.1 Alternative Vergleichsmuster  downtop

Um gleich wieder auf das Script »acase1« zurückzukommen: Ein Problem, das hierbei auftreten kann, ist, dass die deutsche Schreibweise für den Wochentag verwendet wurde. Was aber, wenn die Umgebung in einer englischsprachigen Welt liegt, in der eben die Wochentage »Mon«, »Tue«, »Wed«, »Thu«, »Fri«, »Sat« und »Sun« heißen? Hierzu bietet Ihnen case in der Auswahlliste alternative Vergleichsmuster an. Sie können mehrere Muster zur Auswahl stellen. Die Muster werden mit dem bitweisen ODER-( | )-Operator getrennt.

case "$var" in
   muster1a|muster1b|muster1c)   kommando
                                 ...
                                 kommando ;;
   muster2a|muster2b|muster2c)   kommando
                                 ...
                                 kommando ;;
   muster3a|muster3b|muster3c)   kommando
                                 ...
                                 kommando ;;
esac

Wenden Sie dies nun auf das Script »acase1« an, so haben Sie ein Script erstellt, das sowohl die Ausgabe des deutschen als auch des englischsprachigen Wochentags akzeptiert.

# Demonstriert die case-Anweisung und die
# alternativen Vergleichsmuster
# acase2
tag=`date +%a`
case "$tag" in
  Mo|Mon)   echo "Mo : Backup Datenbank machen" ;;
  Di|Tue)   echo "Di : Backup Rechner Saurus"   ;;
  Mi|Wed)   echo "Mi : Backup Rechner Home"     ;;
  Do|Thu)   echo "Do : Backup Datenbank machen" ;;
  Fr|Fri)   echo "Fr : Backup Rechner Saurus"   ;;
  Sa|Sat)   echo "Sa : Backup Rechner Home"     ;;
  So|Sun)   echo "So : Sämtliche Backups auf CD-R sichern" ;;
esac

Das Beispiel kann man nochmals verkürzen, da ja am Montag und Donnerstag, Dienstag und Freitag sowie Mittwoch und Samstag dieselbe Arbeit gemacht wird.

# Demonstriert die case-Anweisung und die alternativen Vergleichsmuster
# acase3
tag=`date +%a`
case "$tag" in
  Mo|Mon|Do|Thu)   echo "$tag : Backup Datenbank machen" ;;
  Di|Tue|Fr|Fri)   echo "$tag : Backup Rechner Saurus"   ;;
  Mi|Wed|Sa|Sat)   echo "$tag : Backup Rechner Home"     ;;
  So|Sun)   echo "So : Sämtliche Backups auf CD-R sichern" ;;
esac

Rheinwerk Computing

4.8.2 case und Wildcards  downtop

Bei den Mustern der case-Anweisung sind auch alle Wildcard-Zeichen erlaubt, die Sie von der Dateinamen-Substitution her kennen. Die Muster-Alternativen wie bspw. *(...|...|...); @(...|...|...) bleiben weiterhin nur der Bash und der Korn-Shell vorbehalten. Auch hier kann wieder z. B. das Script »acase3« einspringen. Wenn alle Tage überprüft wurden, ist es eigentlich nicht mehr erforderlich, den Sonntag zu überprüfen. Hierfür könnte man jetzt theoretisch auch das Wildcard-Zeichen * verwenden.

# Demonstriert die case-Anweisung und die
# alternativen Vergleichsmuster mit Wildcards
# acase4
tag=`date +%a`
case "$tag" in
  Mo|Mon|Do|Thu)   echo "$tag : Backup Datenbank machen" ;;
  Di|Tue|Fr|Fri)   echo "$tag : Backup Rechner Saurus"   ;;
  Mi|Wed|Sa|Sat)   echo "$tag : Backup Rechner Home"     ;;
  *)   echo "So : Sämtliche Backups auf CD-R sichern" ;;
esac

Das Wildcard-Zeichen wird in einer case-Anweisung immer als letztes Alternativ-Muster eingesetzt, wenn bei den Mustervergleichen zuvor keine Übereinstimmung gefunden wurde. Somit führt der Vergleich mit * immer zum Erfolg und wird folglich auch immer ausgeführt, wenn keines der Mustervergleiche zuvor gepasst hat. Das * steht im Vergleich zur if-elif-Verzweigung für die else-Alternative.

Die Wildcards [] lassen sich bspw. hervorragend einsetzen, wenn Sie nicht sicher sein können, ob der Anwender Groß- und/oder Kleinbuchstaben bei der Eingabe verwendet. Wollen Sie bspw. überprüfen, ob der Benutzer für eine Ja-Antwort, »j«, »J« oder »ja« bzw. »Ja« oder »JA« verwendet hat, können Sie dies folgendermaßen mit den Wildcards [] vornehmen.

# Demonstriert die case-Anweisung mit Wildcards
# acase5
# Als erstes Argument angeben
case "$1" in
   [jJ] )            echo "Ja!"    ;;
   [jJ][aA])         echo "Ja!"    ;;
   [nN])             echo "Nein!"  ;;
   [nN][eE][iI][nN]) echo "Nein!"  ;;
   *)                echo "Usage $0 [ja] [nein]" ;;
esac

Das Script bei der Ausführung:

you@host > ./acase1
Usage ./acase1 [ja] [nein]
you@host > ./acase1 j
Ja!
you@host > ./acase1 jA
Ja!
you@host > ./acase1 nEIn
Nein!
you@host > ./acase1 N
Nein!
you@host > ./acase1 n
Nein!
you@host > ./acase1 Ja
Ja!

Das Ganze lässt sich natürlich mit Vergleichsmustern wiederum erheblich verkürzen:

# Demonstriert die case-Anweisung mit Wildcards und
# alternativen Mustervergleichen
# acase6
# Als erstes Argument angeben
case "$1" in
   [jJ]|[jJ][aA])          echo "Ja!"    ;;
   [nN]|[nN][eE][iI][nN])  echo "Nein!"  ;;
   *)                      echo "Usage $0 [ja] [nein]" ;;
esac

Rheinwerk Computing

4.8.3 case und Optionen  toptop

Zu guter Letzt eignet sich case hervorragend zum Auswerten von Optionen in der Kommandozeile. Ein einfaches Beispiel:

# Demonstriert die case-Anweisung zum Auswerten von Optionen
# acase7
# Als erstes Argument angeben
case "$1" in
   -[tT]|-test)        echo "Option \"test\" aufgerufen"  ;;
   -[hH]|-help|-hilfe) echo "Option \"hilfe\" aufgerufen" ;;
   *)                  echo "($1) Unbekannte Option aufgerufen!"
esac

Das Script bei der Ausführung:

you@host > ./acase1 -t
Option "test" aufgerufen
you@host > ./acase1 -test
Option "test" aufgerufen
you@host > ./acase1 -h
Option "hilfe" aufgerufen
you@host > ./acase1 -hilfe
Option "hilfe" aufgerufen
you@host > ./acase1 -H
Option "hilfe" aufgerufen
you@host > ./acase1 -zzz
(-zzz) Unbekannte Option aufgerufen!

Sie können hierfür wie gewohnt die Optionen der Kommandozeile mit dem Kommando getopts (siehe Abschnitt 3.8) auswerten, zum Beispiel:

# Demonstriert die case-Anweisung zum Auswerten von
# Optionen mit getopts
# acase8
while getopts tThH opt 2>/dev/null
do
   case $opt in
       t|T) echo "Option test";;
       h|H) echo "Option hilfe";;
       ?) echo "($0): Ein Fehler bei der Optionsangabe"
   esac
done


Ihre Meinung

Wie hat Ihnen das Openbook gefallen? Wir freuen uns immer über Ihre Rückmeldung. Schreiben Sie uns gerne Ihr Feedback als E-Mail an kommunikation@rheinwerk-verlag.de.

 << zurück
  
  Zum Rheinwerk-Shop
Zum Rheinwerk-Shop: Shell-Programmierung
Shell-Programmierung
bestellen
 Buchtipps
Zum Rheinwerk-Shop: Shell-Programmierung






 Shell-Programmierung


Zum Rheinwerk-Shop: Linux-Server






 Linux-Server


Zum Rheinwerk-Shop: Das Komplettpaket LPIC-1 & LPIC-2






 Das Komplettpaket
 LPIC-1 & LPIC-2


Zum Rheinwerk-Shop: Linux-Hochverfügbarkeit






 Linux-
 Hochverfügbarkeit


Zum Rheinwerk-Shop: Linux Handbuch






 Linux Handbuch


 Lieferung
Versandkostenfrei bestellen in Deutschland, Österreich und der Schweiz
InfoInfo





Copyright © Rheinwerk Verlag GmbH 2005
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das Openbook denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt.
Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


Nutzungsbestimmungen | Datenschutz | Impressum

Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de

Cookie-Einstellungen ändern