Bedingte Anweisung (if - then - else)
Wichtig: Als Bedingung kann nicht nur der test-Befehl, sondern eine beliebige
Folge von Kommados verwendet werden. Jedes Kommando liefert einen Errorcode zurück, der bei erfolgreicher Ausführung gleich Null (true) und bei einem Fehler oder Abbruch ungleich Null (false) ist. Zum Testen einer Bedingung dient die if-Anweisung. Jede Anweisung muß entweder in einer eigenen Zeile stehen oder durch einen Strichpunkt von den anderen Anweisungen getrennt werden. Trotzdem verhät sicheine bedingte Anweisung - oder die Schleifenkonstrukte, die weiter untenbehandelt werden - wie eine einzige Anweisung. Somit ergibt sich eine starke Ähnlichkeit mit der Blockstruktur von C oder Pascal. Man kann dies ausprobieren,indem man eine if- oder while-Anweisung interaktiv eingibt. Solange nicht 'fi' bzw. 'done' eingetippt wurde, erhält man den PS2-Prompt ('>').
einseitiges if:
if kommandoliste
then
kommandos
fi
zweiseitiges if:
if kommandoliste
then
kommandos
else
kommandos
fi
mehrstufiges if:
if kommandoliste1
then
kommandos
elif kommandoliste2
then
kommandos
elif ...
...
fi
Beispiele für die if-Anweisung:
Es soll eine Meldung ausgegeben werden, falls mehr als 5 Benutzer eingeloggt sind:
USERS=`who | wc -l` # Zeilen der who-Ausgabe zählen
if test $USERS -gt 5
then
echo "Mehr als 5 Benutzer am Geraet"
fi
Das geht natürlich auch kürzer und ohne Backtics:
if [ $(who | wc -l) -gt 5 ] ; then
echo "Mehr als 5 Benutzer am Geraet"
fi
Man sollte bei der Entwicklung von Skripts aber ruhig mit der Langfassung beginnen
und sich erst der Kurzfassung zuwenden, wenn man mehr Übung hat und die Langfassungen
auf Anhieb funktionieren. Ein weiteres Beispiel zeigt eine Fehlerprüfung:
if test $# -eq 0
then
echo "usage: sortiere filename" >&2
else
sort +1 -2 $1 | lp
fi
Das nächste Beispiel zeigt eine mehr oder weniger intelligente Anzeige für
Dateien und Verzeichnisse. 'show' zeigt bei Dateien den Inhalt mit 'less' an und
Verzeichnisse werden mit 'ls' präsentiert. Fehlt der Parameter, wird interaktiv
nachgefragt:
if [ $# -eq 0 ] # falls keine Angabe
then # interaktiv erfragen
echo -n "Bitte Namen eingeben: "
read DATEI
else
DATEI=$1
fi
if [-f $DATEI ] # wenn normale Datei
then # dann ausgeben
less $DATEI
elif [ -d $DATEI ] # wenn aber Verzeichnis
then # dann Dateien zeigen
ls -CF $DATEI
else # sonst Fehlermeldung
echo "cannot show $DATEI"
fi
Das nächste Beispiel hängt eine Datei an eine andere Datei an; vorher
erfolgt eine Prüfung der Zugriffsberechtigungen: append Datei1 Datei2
if [ -r $1 -a -w $2 ]
then
cat $1 >> $2
else
echo "cannot append"
fi
Beim Vergleich von Zeichenketten sollten möglichst die Anführungszeichen
(" ... ") verwendet werden, da sonst bei der Ersetzung durch die Shell
unvollständige Test-Kommandos entstehen können. Dazu ein Beispiel:
if [ ! -n $1 ] ; then
echo "Kein Parameter"
fi
Ist $1 wirklich nicht angegeben, wird das Kommando reduziert zu:
if [ ! -n ] ; then ....
Es ist also unvollständig und es erfolgt eine Fehlermeldung. Dagegen liefert
if [ ! -n "$1" ] ; then
echo "Kein Parameter"
fi
bei fehlendem Parameter den korrekten Befehl if [ ! -n "" ]
Bei fehlenden Anführungszeichen werden auch führende Leerzeichen der
Variablenwerte oder Parameter eliminiert.
Noch ein Beispiel: Es kommt ab und zu vor, daß eine Userid wechselt oder
daß die Gruppenzugehörigkeit von Dateien geändert werden muß.
In solchen fällen helfen die beiden folgenden Skripts:
!/bin/sh
# Change user-id
#
if [ $# -ne 2 ] ; then
echo "usage `basename $0` <old id> <new id>"
exit
fi
find / -user $1 -exec chown $2 {} ";"
#!/bin/sh
# Change group-id
#
if [ $# -ne 2 ] ; then
echo "usage `basename $0` <old id> <new id>"
exit
fi
find / -group $1 -exec chgrp $2 {} ";"
|