Technique classique (métacaractères d'échappement):
if [ \( "$g" -eq 1 -a "$c" = "123" \) -o \( "$g" -eq 2 -a "$c" = "456" \) ]
then echo abc
else echo efg
fi
J'ai joint les références à $gentre guillemets; c'est une bonne pratique, en général. Strictement, les parenthèses ne sont pas nécessaires car la priorité de -aet la -orend correcte même sans elles.
Notez que les opérateurs -aet -ofont partie de la spécification POSIX pour test, alias [, principalement pour la compatibilité descendante (car ils faisaient partie de la test7e édition UNIX, par exemple), mais ils sont explicitement marqués comme `` obsolètes '' par POSIX. Bash (voir les expressions conditionnelles ) semble préempter les significations classiques et POSIX pour -aet -oavec ses propres opérateurs alternatifs qui prennent des arguments.
Avec un peu de soin, vous pouvez utiliser l' [[opérateur le plus moderne , mais sachez que les versions dans Bash et Korn Shell (par exemple) n'ont pas besoin d'être identiques.
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
Exemple d'exécution, en utilisant Bash 3.2.57 sur 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
Vous n'avez pas besoin de citer les variables [[comme vous le faites [car ce n'est pas une commande distincte de la même manière [.
N'est-ce pas une question classique?
Je l'aurais pensé. Cependant, il existe une autre alternative, à savoir:
if [ "$g" -eq 1 -a "$c" = "123" ] || [ "$g" -eq 2 -a "$c" = "456" ]
then echo abc
else echo efg
fi
En effet, si vous lisez les directives du «shell portable» pour l' autoconfoutil ou les packages associés, cette notation - en utilisant « ||» et « &&» - est ce qu'ils recommandent. Je suppose que vous pourriez même aller jusqu'à:
if [ "$g" -eq 1 ] && [ "$c" = "123" ]
then echo abc
elif [ "$g" -eq 2 ] && [ "$c" = "456" ]
then echo abc
else echo efg
fi
Lorsque les actions sont aussi triviales que l'écho, ce n'est pas mauvais. Lorsque le bloc d'action à répéter est composé de plusieurs lignes, la répétition est trop douloureuse et l'une des versions antérieures est préférable - ou vous devez encapsuler les actions dans une fonction qui est invoquée dans les différents thenblocs.
test([) et non par le shell. Le shell évalue uniquement l'état de sortie de[.