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 $g
in doppelte Anführungszeichen gesetzt; Das ist im Allgemeinen eine gute Praxis. Streng genommen werden die Klammern nicht benötigt, da sie Vorrang haben -a
und -o
auch ohne sie korrekt sind.
Beachten Sie, dass die Operatoren -a
und -o
Teil der POSIX-Spezifikation test
sind [
, vor allem aus Gründen der Abwärtskompatibilität (da sie beispielsweise Teil der test
7. 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 -a
und -o
mit 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 autoconf
Tool 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 then
Blöcken aufgerufen wird .
test
([
) und nicht von der Shell ausgewertet . Die Shell wertet nur den Exit-Status von aus[
.