Klassische Technik (Escape-Metazeichen):
if [ \( "$g" -eq 1 -a "$c" = "123" \) -o \( "$g" -eq 2 -a "$c" = "456" \) ]
then echo abc
else echo efg
fi
Ich habe die Verweise auf $gin doppelte Anführungszeichen gesetzt; Das ist im Allgemeinen eine gute Praxis. Streng genommen werden die Klammern nicht benötigt, da sie Vorrang haben -aund -oauch ohne sie korrekt sind.
Beachten Sie, dass die Operatoren -aund -oTeil der POSIX-Spezifikation testsind [, vor allem aus Gründen der Abwärtskompatibilität (da sie beispielsweise Teil der test7. Edition von UNIX waren), von POSIX jedoch ausdrücklich als "veraltet" gekennzeichnet werden. Bash (siehe bedingte Ausdrücke ) scheint die klassischen und POSIX-Bedeutungen für -aund -omit eigenen alternativen Operatoren, die Argumente annehmen, zu verhindern.
Mit einiger Sorgfalt können Sie den moderneren [[Operator verwenden. Beachten Sie jedoch, dass die Versionen in Bash und Korn Shell (zum Beispiel) nicht identisch sein müssen.
for g in 1 2 3
do
for c in 123 456 789
do
if [[ ( "$g" -eq 1 && "$c" = "123" ) || ( "$g" -eq 2 && "$c" = "456" ) ]]
then echo "g = $g; c = $c; true"
else echo "g = $g; c = $c; false"
fi
done
done
Beispiellauf mit Bash 3.2.57 unter Mac OS X:
g = 1; c = 123; true
g = 1; c = 456; false
g = 1; c = 789; false
g = 2; c = 123; false
g = 2; c = 456; true
g = 2; c = 789; false
g = 3; c = 123; false
g = 3; c = 456; false
g = 3; c = 789; false
Sie brauchen nicht die Variablen in zitieren , [[wie Sie mit zu tun , [weil es nicht ein separater Befehl in der gleichen Art und Weise, die [ist.
Ist das nicht eine klassische Frage?
Das hätte ich mir gedacht. Es gibt jedoch eine andere Alternative, nämlich:
if [ "$g" -eq 1 -a "$c" = "123" ] || [ "$g" -eq 2 -a "$c" = "456" ]
then echo abc
else echo efg
fi
Wenn Sie die Richtlinien für tragbare Shell für das autoconfTool oder verwandte Pakete lesen , wird diese Notation - mit ' ||' und ' &&' - empfohlen. Ich nehme an, Sie könnten sogar so weit gehen:
if [ "$g" -eq 1 ] && [ "$c" = "123" ]
then echo abc
elif [ "$g" -eq 2 ] && [ "$c" = "456" ]
then echo abc
else echo efg
fi
Wo die Aktionen so trivial sind wie Echo, ist das nicht schlecht. Wenn der zu wiederholende Aktionsblock aus mehreren Zeilen besteht, ist die Wiederholung zu schmerzhaft und eine der früheren Versionen ist vorzuziehen - oder Sie müssen die Aktionen in eine Funktion einschließen, die in den verschiedenen thenBlöcken aufgerufen wird .
test([) und nicht von der Shell ausgewertet . Die Shell wertet nur den Exit-Status von aus[.