J'essaie de comprendre comment fonctionne la priorité des opérateurs logiques dans bash. Par exemple, je m'attendais à ce que la commande suivante ne fasse écho à rien.
true || echo aaa && echo bbb
Cependant, contrairement à mes attentes, bbb
est imprimé.
Quelqu'un peut-il expliquer, s'il vous plaît, comment puis-je donner un sens à &&
composé et ||
opérateurs en bash ?
Réponse acceptée :
Dans de nombreux langages informatiques, les opérateurs ayant la même priorité sont associatifs à gauche. Autrement dit, en l'absence de structures de regroupement, les opérations les plus à gauche sont exécutées en premier. Bash ne fait pas exception à cette règle.
Ceci est important car, dans Bash, &&
et ||
ont la même priorité.
Donc, ce qui se passe dans votre exemple, c'est que l'opération la plus à gauche (||
) est effectuée en premier :
true || echo aaa
Depuis true
est évidemment vrai, le ||
les courts-circuits de l'opérateur et l'ensemble de l'énoncé est considéré comme vrai sans qu'il soit nécessaire d'évaluer echo aaa
comme vous vous en doutez. Il reste maintenant à faire l'opération la plus à droite :
(...) && echo bbb
Puisque la première opération a été évaluée comme vraie (c'est-à-dire qu'elle avait un statut de sortie de 0), c'est comme si vous exécutiez
true && echo bbb
donc le &&
ne court-circuitera pas, c'est pourquoi vous voyez bbb
fait écho.
Vous obtiendriez le même comportement avec
false && echo aaa || echo bbb
Notes basées sur les commentaires
- Vous devez noter que la règle d'associativité à gauche est seulement suivi lorsque les deux opérateurs ont le même priorité. Ce n'est pas le cas lorsque vous utilisez ces opérateurs conjointement avec des mots-clés tels que
[[...]]
ou((...))
ou utilisez le-o
et-a
opérateurs comme arguments dutest
ou[
commandes. Dans ce cas, ET (&&
ou-a
) a priorité sur OR (||
ou-o
). Merci au commentaire de Stéphane Chazelas pour avoir éclairci ce point. -
Il semble que dans les langages C et C-like
&&
a une priorité plus élevée que||
c'est probablement pourquoi vous vous attendiez à ce que votre construction d'origine se comporte commetrue || (echo aaa && echo bbb).
Ce n'est pas le cas avec Bash, cependant, dans lequel les deux opérateurs ont la même priorité, c'est pourquoi Bash analyse votre expression en utilisant la règle d'associativité à gauche. Merci au commentaire de Kevin d'avoir soulevé cette question.
-
Il peut également y avoir des cas où tous les 3 les expressions sont évaluées. Si la première commande renvoie un état de sortie différent de zéro, le
||
ne court-circuitera pas et continue d'exécuter la deuxième commande. Si la deuxième commande revient avec un état de sortie nul, alors le&&
ne court-circuitera pas non plus et la troisième commande sera exécutée. Merci au commentaire d'Ignacio Vazquez-Abrams d'avoir soulevé cette question.