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 à $g
entre guillemets; c'est une bonne pratique, en général. Strictement, les parenthèses ne sont pas nécessaires car la priorité de -a
et la -o
rend correcte même sans elles.
Notez que les opérateurs -a
et -o
font partie de la spécification POSIX pour test
, alias [
, principalement pour la compatibilité descendante (car ils faisaient partie de la test
7e é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 -a
et -o
avec 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' autoconf
outil 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 then
blocs.
test
([
) et non par le shell. Le shell évalue uniquement l'état de sortie de[
.