Dans un script, les opérations sont exécutées dans l'ordre de précédence : les opérations ayant une précédence élevée s'exécutent avant celles de précédence plus faible. [37]
Tableau 8.1. Précédence des opérateurs
Opérateur | Signification | Commentaires |
---|---|---|
PLUS HAUTE PRÉCÉDENCE | ||
var++ var-- | post-incrément, post-décrément | Opérateurs style C |
++var --var | pre-incrément, pre-décrément | |
! ~ | négation | logique / bit, inverse le sens de l'opérateur qui suit |
** | exposant | opération arithmétique |
* / % | multiplication, division, modulo | opération arithmétique |
+ - | addition, soustraction | opération arithmétique |
<< >> | décalage à gauche et à droite | bit |
-z -n | comparaison unitaire | chaîne est/n'est pas null |
-e -f -t -x, etc. | comparaison unitaire | fichier test |
< -lt > -gt <= -le >= -ge | comparaison composée | string and integer |
-nt -ot -ef | comparaison composée | fichier test |
== -eq != -ne | égalité / différence | opérateurs de test, chaîne et entier |
& | AND | bit |
^ | XOR | OU exclusif, bit |
| | OU | bit |
&& -a | ET | logique, comparaison composée |
|| -o | OR | logique, comparaison composée |
?: | opérateur à trois arguments | C-style |
= | affectation | (ne pas confondre avec les tests d'égalité) |
*= /= %= += -= <<= >>= &= | combinaison d'affectation | égal + multiplication, égal + division, égal + modulo, etc. |
, | virgule | lie un ensemble d'operations |
PLUS BASSE PRÉCÉDENCE |
En pratique, vous avez seulement besoin de vous rappeler ce qui suit :
Le mantra « My Dear Aunt Sally » (les initiales forment l'acronyme de multiplication, division, addition, soustraction) pour les opérations arithmétiques habituelles.
Les opérateurs logiques composés, &&, ||, -a et -o ont une faible précédence.
L'ordre d'évaluation des opérateurs de précédence identique est généralement de gauche à droite.
À présent, utilisons les connaissances acquises sur la précédence des opérateurs pour analyser quelques-unes des lignes du fichier /etc/init.d/functions trouvé dans la distribution Fedora Core.
while [ -n "$remaining" -a "$retry" -gt 0 ]; do # À première vue c'est compliqué. # Séparer les conditions : while [ -n "$remaining" -a "$retry" -gt 0 ]; do # --condition 1-- ^^ --condition 2- # Si la variable "$remaining" n'est pas vide #+ ET (-a) #+ que la valeur de la variable "$retry" est supérieure à zéro #+ alors #+ l' [ expression-entre-crochets ] renvoit le code de succès (0) #+ et la boucle while exécute une itération. # ============================================================== # Évaluer "condition 1" et "condition 2" ***avant*** #+ de les combiner avec AND. # Pourquoi ? Parce que AND (-a) a une précédence plus basse #+ que les opérateurs -n et -gt, #+ et, du coup, est évalué *en dernier*. ################################################################# if [ -f /etc/sysconfig/i18n -a -z "${NOLOCALE:-}" ] ; then # De nouveau, séparer les conditions : if [ -f /etc/sysconfig/i18n -a -z "${NOLOCALE:-}" ] ; then # --condition 1--------- ^^ --condition 2----- # Si le fichier "/etc/sysconfig/i18n" existe #+ ET (-a) #+ que la variable $NOLOCALE est vide #+ alors #+ le [ test-expression-dans-les-crochets ] renvoit le code de succès (0) #+ et les commandes qui suivent sont exécutées. # # Comme auparavant, le AND (-a) est évalué en *dernier* #+ parce qu'il a une précédence plus basse que les tests entre crochets. # ============================================================== # Note : # ${NOLOCALE:-} est l'expansion d'un paramètre qui semble redondant. # Mais, si $NOLOCALE n'a pas été déclaré, elle est initialisé à *null*, #+ donc réellement déclarée. # Ceci représente une différence essentielle dans certains contextes.
Pour éviter toutes confusion et erreurs dans une séquence complexe d'opérateurs de tests, il vaut mieux découper la séquence en sections entre crochets.
if [ "$v1" -gt "$v2" -o "$v1" -lt "$v2" -a -e "v" ] # Difficile de savoir ce qu'il s'y passe... if [[ "$v1" -gt "$v2" ]] || [[ "$v1" -lt "$v2" ]] && [[ -e "$nomfichier" ]] # Bien préférable -- les tests sont regroupés en sections logiques.