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. [88]
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 | fichiers |
< -lt > -gt <= -le >= -ge | comparaison composée | string and integer |
-nt -ot -ef | comparaison composée | fichiers |
== -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.