Klassische Technik (Metazeichen escapen):
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 sind die Klammern nicht erforderlich, da die Priorität von -a
und -o
auch ohne sie korrekt ist.
Beachten Sie, dass die Operatoren -a
und -o
Teil der POSIX-Spezifikation für test
sind, auch bekannt als [
, hauptsächlich aus Gründen der Abwärtskompatibilität (da sie beispielsweise ein Teil von test
in der 7. Edition von UNIX waren), aber von POSIX ausdrücklich als 'veraltet' gekennzeichnet sind. Bash (siehe bedingte Ausdrücke) scheint die klassische und POSIX-Bedeutung von -a
und -o
Mit etwas Vorsicht können Sie den moderneren [[
-Operator verwenden, aber beachten Sie, dass die Versionen in Bash und Korn-Shell (beispielsweise) nicht unbedingt 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
Beispielablauf unter Verwendung von Bash 3.2.57 auf 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 müssen die Variablen in [[
nicht in Anführungszeichen setzen, wie bei [
, da es kein separates Kommando ist, so wie es [
ist.
Ist es nicht eine klassische Frage?
Hätte ich gedacht. Es gibt jedoch eine weitere Alternative, nämlich:
if [ "$g" -eq 1 -a "$c" = "123" ] || [ "$g" -eq 2 -a "$c" = "456" ]
then echo abc
else echo efg
fi
Tatsächlich empfehlen die 'portable shell'-Richtlinien für das Werkzeug autoconf
oder verwandte Pakete diese Notation - mit '||
' und '&&
'. Ich denke, man könnte 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
Bei so trivialen Aktionen wie dem Echo ist das nicht schlecht. Wenn der Aktionsblock, der wiederholt werden soll, mehrere Zeilen lang ist, ist die Wiederholung zu schmerzhaft und eine der früheren Versionen ist vorzuziehen - oder Sie müssen die Aktionen in eine Funktion einbinden, die in den verschiedenen then
-Blöcken aufgerufen wird.
9 Stimmen
Sie fragen nicht nach Shell-Bedingungen, sondern nach Test-Bedingungen. Der gesamte Ausdruck in Ihrem Beispiel wird von
test
([
) und nicht von der Shell ausgewertet. Die Shell bewertet nur den Exit-Status von[
.0 Stimmen
Siehe auch stackoverflow.com/questions/16203088/…
0 Stimmen
Verwandt: Zusammengesetzte if-Anweisungen mit mehreren Ausdrücken in Bash