33.2. Précédence des opérateurs

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 :

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.
[Astuce]

Astuce

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.


[100] La précédence, dans ce contexte, correspond en quelque sorte à une priorité.