Dans un script, les opérations sont exécutées dans l'ordre de précédence : les opérations de plus haute précédence s'exécutent avant celles de plus basse. [100]
Tableau 33.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 de logiques composés, &&, ||, -a, et -o ont une basse précédence.
L'ordre d'évaluation des opérateurs de précédence identique est habituellement de gauche à droite.
Maintenant, utilisons nos connaissances de la précédence des opérateurs pour analyser quelques lignes du fichier /etc/init.d/functions trouvé dans la distribution Fedora Core.
while [ -n "$remaining" -a "$retry" -gt 0 ]; do
# Cela semble complexe à première vue.
# 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 grouper 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 suivantes 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, dans les faits, la déclare.
# Ceci représente une différence essentielle dans certains contextes.
Pour éviter la confusion ou des erreurs dans une séquence complexe d'opérateurs de tests, cassez 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 mieux -- les tests sont groupés en sections logiques.