4.6 Logische Verknüpfung von Ausdrücken
Wie die meisten anderen Programmiersprachen bietet Ihnen auch die Shell logische Operatoren an, mithilfe derer Sie mehrere Bedingungen miteinander verknüpfen können. Folgende logische Operatoren sind bei allen Shells vorhanden (siehe Tabelle 4.8):
Tabelle 4.8
Logische Operatoren
Operator
|
Logischer Wert
|
Gibt wahr (0) zurück, wenn ...
|
ausdruck1 –a ausdruck2
|
(and) UND
|
beide Ausdrücke wahr zurückgeben.
|
ausdruck1 –o ausdruck2
|
(or) ODER
|
mindestens einer der beiden Ausdrücke wahr ist.
|
! ausdruck
|
Negation
|
der Ausdruck falsch ist.
|
In der Bash und der Korn-Shell finden Sie noch eine andere Syntax für die logischen Operatoren UND und ODER (siehe Tabelle 4.9).
Tabelle 4.9
Logische Operatoren (Bash und Korn-Shell)
Operator
|
Logischer Wert
|
Gibt wahr (0) zurück, wenn ...
|
ausdruck1 && ausdruck2
|
(and) UND
|
beide Ausdrücke wahr zurückgeben.
|
ausdruck1 || ausdruck2
|
(or) ODER
|
mindestens einer der beiden Ausdrücke wahr ist.
|
4.6.1 Negationsoperator !
Den Negationsoperator ! können Sie vor jeden Ausdruck setzen. Als Ergebnis des Tests erhalten Sie immer das Gegenteil. Alles, was ohne ! wahr wäre, ist falsch und alles, was falsch ist, wäre dann wahr.
# Demonstriert Dateitest mit Negation
# anegation
file=atestfile.txt
# Eine Datei anlegen
if [ ! -e $file ]
then
touch $file
if [ ! -e $file ]
then
echo "Konnte $file nicht anlegen"
exit 1
fi
fi
echo "$file angelegt/vorhanden!"
Im Beispiel wird zuerst ausgewertet, ob die Datei atestfile.txt bereits existiert. Existiert sie nicht, wird ein Wert ungleich 0 zurückgegeben und es wird nicht in die if-Verzweigung gesprungen. Allerdings wurde hier durch das Voranstellen des Negationsoperators ! der Ausdruck umgekehrt. Und somit wird in den if-Zweig gesprungen, wenn die Datei nicht existiert. Bei Nicht-Existenz entsprechender Datei wird diese neu erzeugt (mit touch). Anschließend wird selbige Überprüfung nochmals durchgeführt.
Hinweis Bitte beachten Sie, dass die echte Bourne-Shell den Negationsoperator außerhalb des test-Kommandos nicht kennt.
|
4.6.2 Die UND-Verknüpfung (-a und &&)
Bei einer UND-Verknüpfung müssen alle verwendeten Ausdrücke wahr sein, damit der komplette Ausdruck ebenfalls wahr (0) wird. Sobald ein Ausdruck einen Wert ungleich 0 zurückgibt, gilt der komplette Ausdruck als falsch. Siehe Abbildung 4.6:
Ein einfaches Beispiel:
# Demonstriert die logische UND-Verknüpfung
# aandtest
file=atestfile.txt
# Eine Datei anlegen
if [ -f $file -a -w $file ]
then
echo "Datei $file ist eine reguläre Datei und beschreibbar"
fi
Hier wird überprüft, ob die Datei atestfile.txt eine reguläre Datei UND beschreibbar ist. Gleiches mit dem alternativen UND-Operator && in der Bash oder der Korn-Shell wird wie folgt geschrieben:
if [ -f $file ] && [ -w $file ]
Wollen Sie überprüfen, ob eine Zahl einen Wert zwischen 1 und 10 besitzt, kann der UND-Operator wie folgt verwendet werden (hier kann der Wert als erstes Argument der Kommandozeile mit übergeben werden, ansonsten wird als Alternative einfach der Wert 5 verwendet):
# Demonstriert den UND-Operator
# aandnumber
number=${1:-"5"}
# Eine Datei anlegen
if [ $number -gt 0 -a $number -lt 11 ]
then
echo "Wert liegt zwischen 1 und 10"
else
echo "Wert liegt nicht zwischen 1 und 10"
fi
Das Script bei der Ausführung:
you@host > ./aandnumber 9
Wert liegt zwischen 1 und 10
you@host > ./aandnumber 0
Wert liegt nicht zwischen 1 und 10
you@host > ./aandnumber 11
Wert liegt nicht zwischen 1 und 10
you@host > ./aandnumber 10
Wert liegt zwischen 1 und 10
Natürlich dürfen Sie auch hier wieder die alternative Syntax der Bash bzw. der Korn-Shell verwenden:
if (( $number > 0 )) && (( $number < 11 ))
4.6.3 Die ODER-Verknüpfung (-o und ||)
Eine ODER-Verknüpfung liefert bereits wahr zurück, wenn nur einer der Ausdrücke innerhalb der Verknüpfung wahr ist. Siehe Abbildung 4.7:
if (( $number == 1 )) || (( $number == 2 ))
Hier wird bspw. wahr zurückgeliefert, wenn der Wert von »number« 1 oder 2 ist. Gleiches in der Bourne-Shell:
if [ $number -eq 1 -o $number -eq 2 ]
Ähnliches wird häufig verwendet, um zu überprüfen, ob ein Anwender »j« oder »ja« bzw. »n« oder »nein« zur Bestätigung einer Abfrage eingegeben hat:
if [ $answer = "j" -o $answer = "ja" ]
if [ $answer = "n" -o $answer = "nein" ]
Alternativ für »neuere« Shells:
if [[ $answer == "j" ]] || [[ $answer == "ja" ]]
if [[ $answer == "n" ]] || [[ $answer == "nein" ]]
4.6.4 Klammerung und mehrere logische Verknüpfungen
Die Auswertung von Ausdrücken kann entweder innerhalb oder außerhalb der Klammern erfolgen – wobei dies in der Bash bzw. der Korn-Shell das Gleiche bedeutet. Mithilfe von Klammerungen können Sie die Reihenfolge bei der Auswertung von logischen Ausdrücken bestimmen. Dies natürlich nur, solange sich die Ausdrücke innerhalb von runden (( )), doppelt eckigen [[ ]] oder ganz außerhalb von Klammern befinden.
# Klammerung muss außerhalb von [[ ]] stattfinden
if ([[ $var1 == "abc" ]] && [[ $var2 == "cde" ]]) || \
( [[ $var3 == "abc" ]] )
Hier überprüfen Sie beispielsweise, ob »var1« den Wert »abc« und »var2« den Wert »cde« oder aber »var3« den Wert »abc« enthält. Hier würde also wahr zurückgegeben, wenn der erste Ausdruck, der ja aufgeteilt wurde in zwei Ausdrücke, oder der zweite Ausdruck (hinter dem ODER) wahr zurückgibt. Natürlich können Sie Gleiches auch mit der Bourne-Shell-Kompatibilität vornehmen:
# Innerhalb von eckigen Klammern müssen runde Klammern
# ausgeschaltet werden
if [ \( "$var1" = "abc" -a "$var2" = "cde" \) -o \
"$var3" = "abc" ]
Hierbei (also innerhalb von eckigen Klammern) müssen Sie allerdings die ungeschützten runden Klammern durch einen Backslash ausschalten, denn sonst würde versucht werden, eine Subshell zu öffnen. Doch sollte nicht unerwähnt bleiben, dass die Klammerung hierbei auch entfallen könnte, da folgende Auswertung zum selben Ziel geführt hätte:
# Bash und Korn-Shell
if [[ $var1 == "abc" ]] && [[ $var2 == "cde" ]] || \
[[ $var3 == "abc" ]]
# alle Shells
if [ "$var1" = "abc" -a "$var2" = "cde" -o "$var3" = "abc" ]
Gleiches gilt bei der Klammerung von Zahlenwerten in logischen Ausdrücken:
# Bash und Korn-Shell
if (( $var1 == 4 )) || ( (( $var2 == 2 )) && (( $var3 == 3 )) )
# alle Shells
if [ $var1 -eq 4 -o \( $var2 -eq 2 -a $var3 -eq 3 \) ]
Das Gleiche würde man hier auch ohne Klammerung wie folgt erreichen:
# Bash und Korn-Shell
if (( $var1 == 4 )) || (( $var2 == 2 )) && (( $var3 == 3 ))
# alle Shells
if [ $var1 -eq 4 -o $var2 -eq 2 -a $var3 -eq 3 ]
Hier würde der Ausdruck daraufhin überprüft, ob entweder »var1« gleich 4 ist oder »var2« gleich 2 und »var3« gleich 3. Trifft einer dieser Ausdrücke zu, wird wahr zurückgegeben. In Tabelle 4.10 nochmals die Syntax zu den verschiedenen Klammerungen:
Tabelle 4.10
Verwendung von Klammern bei Ausdrücken
Ausdruck für
|
Ohne Klammern
|
Klammerung
|
Shell
|
Zeichenketten
|
[[ Ausdruck ]]
|
([[ Ausdruck ]])
|
Bash und Korn
|
Zeichenketten
|
[ Ausdruck ]
|
[ \( Ausdruck \) ]
|
alle Shells
|
Zahlenwerte
|
(( Ausdruck ))
|
( (( Ausdruck )) )
|
Bash und Korn
|
Zahlenwerte
|
[ Ausdruck ]
|
[ \( Ausdruck \) ]
|
alle Shells
|
Dateitest
|
[ Ausdruck ]
|
[ \( Ausdruck \) ]
|
alle Shells
|
Dateitest
|
[[ Ausdruck ]]
|
([[ Ausdruck ]])
|
nur Korn
|
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.
|