Un opérateur de comparaison binaire compare deux variables ou quantités. Notez que la comparaison entre entiers et chaînes utilisent un différent ensemble d'opérateurs.
comparaison d'entiers
est égal à
if [ "$a" -eq "$b" ]
n'est pas égal à
if [ "$a" -ne "$b" ]
est plus grand que
if ["$a" -gt "$b" ]
est plus grand ou égal à
if [ "$a" -ge "$b" ]
est plus petit que
if [ "$a" -lt "$b" ]
est plus petit ou égal à
if [ "$a" -le "$b" ]
est plus petit que (à l'intérieur de parenthèses doubles)
(("$a" < "$b"))
est plus petit ou égal à (à l'intérieur de parenthèses doubles)
(("$a" <= "$b"))
est plus grand que (à l'intérieur de parenthèses doubles)
(("$a" > "$b"))
est plus grand ou égal à (à l'intérieur de parenthèses doubles)
(("$a" >= "$b"))
comparaison de chaînes de caractères
if [ "$a" = "$b" ]
est égal à
if [ "$a" == "$b" ]
Ceci est un synonyme de =.
L'opérateur de comparaison == se comporte différemment à l'intérieur d'un test à double crochets qu'à l'intérieur de crochets simples.
[[ $a == z* ]] # Vrai si $a commence avec un "z" (correspondance de modèle). [[ $a == "z*" ]] # Vrai si $a est égal à z* (correspondance littérale). [ $a == z* ] # Correspondance de fichiers et découpage de mots. [ "$a" == "z*" ] # Vrai si $a est égal à z* (correspondance littérale). # Merci, Stéphane Chazelas
n'est pas égal à
if [ "$a" != "$b" ]
Cet opérateur utilise la reconnaissance de motifs à l'intérieur de constructions [[ ... ]].
est plus petit que, d'après l'ordre alphabétique ASCII
if [[ "$a" < "$b" ]]
if [ "$a" \< "$b" ]
Notez que « < » a besoin d'être dans une séquence d'échappement s'il se trouve à l'intérieur de [ ].
est plus grand que, d'après l'ordre alphabétique ASCII
if [[ "$a" > "$b" ]]
if [ "$a" \> "$b" ]
Notez que « > » a besoin d'être dans une séquence d'échappement s'il se trouve à l'intérieur de [ ].
Voir l'Exemple 26.10, « Le tri bulle : Bubble Sort » pour une application de cet opérateur de comparaison.
la chaîne de caractères n'est pas « vide ».
Attention : Le test -n nécessite absolument que la chaîne de caractères soit entre guillemets à l'intérieur des crochets de test. Utiliser une chaîne sans guillemets avec ! -z, voire simplement la chaîne sans guillemets à l'intérieur des crochets (voir l'Exemple 7.6, « Vérification si une chaîne est nulle ») fonctionne habituellement, néanmoins, c'est une pratique peu sûre. Placez toujours vos chaînes de caractères à tester entre guillemets. [31]
la chaîne de caractères est « vide », c'est-à-dire qu'elle a une taille nulle
Exemple 7.5. Comparaisons de nombres et de chaînes de caractères
#!/bin/bash a=4 b=5 # Ici, "a" et "b" peuvent être traités soit comme des entiers soit comme des #+ chaînes de caractères. # Il y a un peu de flou entre les comparaisons arithmétiques et de chaînes de #+ caractères car les variables Bash ne sont pas typées fortement. # Bash permet des opérations et des comparaisons d'entiers sur des variables #+ contenant des caractères uniquements numériques. # Néanmoins, faites attention. echo if [ "$a" -ne "$b" ] then echo "$a n'est pas égal à $b" echo "(comparaison arithmétique)" fi echo if [ "$a" != "$b" ] then echo "$a n'est pas égal à $b." echo "(comparaison de chaînes de caractères)" # "4" != "5" # ASCII 52 != ASCII 53 fi # Pour cette instance particulière, "-ne" et "!=" fonctionnent. echo exit 0
Exemple 7.6. Vérification si une chaîne est nulle
#!/bin/bash # str-test.sh: Tester des chaînes nulles et sans guillemets, # "but not strings and sealing wax, not to mention cabbages and kings..." # En utilisant if [ ... ] # Si une chaîne n'a pas été initialisée, elle n'a pas de valeur définie. # Cet état est appelé "null" (ce qui n'est pas identique à zéro). if [ -n $chaine1 ] # $chaine1 n'est ni déclaré ni initialisé. then echo "La chaîne \"chaine1\" n'est pas nulle." else echo "La chaîne \"chaine1\" est nulle." fi # Mauvais résultat. # Affiche $chaine1 comme non nulle bien qu'elle n'ait pas été initialisée. echo # Essayons de nouveau. if [ -n "$chaine1" ] # Cette fois, $chaine1 est entre guillemet. then echo "La chaîne \"chaine1\" n'est pas nulle." else echo "La chaîne \"chaine1\" est nulle." fi # Entourer les chaînes avec des crochets de test. echo if [ $chaine1 ] # Cette fois, $chaine1 est seule. then echo "La chaîne \"chaine1\" n'est pas nulle." else echo "La chaîne \"chaine1\" est nulle." fi # Ceci fonctionne. # L'opérateur de test [ ] tout seul détecte si la chaîne est nulle. # Néanmoins, une bonne pratique serait d'y mettre des guillemets ("$chaine1"). # # Comme Stéphane Chazelas le dit, # if [ $chaine1 ] a un argument, "]" # if [ "$chaine1" ] a deux arguments, la chaîne "$chaine1" vide et "]" echo chaine1=initialisée if [ $chaine1 ] # Une fois encore, $chaine1 est seule. then echo "La chaîne \"chaine1\" n'est pas nulle." else echo "La chaîne \"chaine1\" est nulle." fi # De nouveau, cela donne le résultat correct. # Il est toujours préférable de la mettre entre guillemets ("$chaine1"), parce # que... chaine1="a = b" if [ $chaine1 ] # $chaine1 est de nouveau seule. then echo "La chaîne \"chaine1\" n'est pas nulle." else echo "La chaîne \"chaine1\" est nulle." fi # Ne pas mettre "$chaine1" entre guillemets donne un mauvais résultat ! exit 0 # Merci aussi à Florian Wisser pour le "heads up".
Exemple 7.7. zmore
#!/bin/bash #Visualiser des fichiers gzip avec 'more' SANSARGS=65 PASTROUVE=66 NONGZIP=67 if [ $# -eq 0 ] # même effet que: if [ -z "$1" ] # $1 peut exister mais doit être vide: zmore "" arg2 arg3 then echo "Usage: `basename $0` nomfichier" >&2 # Message d'erreur vers stderr. exit $SANSARGS # Renvoie 65 comme code de sortie du script (code d'erreur). fi nomfichier=$1 if [ ! -f "$nomfichier" ] # Mettre $nomfichier entre guillemets permet d'avoir #+ des espaces dans les noms de fichiers. then echo "Fichier $nomfichier introuvable !" >&2 # Message d'erreur vers stderr. exit $PASTROUVE fi if [ ${nomfichier##*.} != "gz" ] # Utilisation de crochets pour la substitution de variables. then echo "Le fichier $1 n'est pas compressé avec gzip !" exit $NONGZIP fi zcat $1 | more # Utilise le filtre 'more'. # Peut se substituer à 'less', si vous le souhaitez. exit $? # Le script renvoie le code d'erreur du tube. # En fait, "exit $?" n'est pas nécessaire, car le script retournera, pour #+ chaque cas, le code de sortie de la dernière commande exécutée.
Elles sont similaires aux opérateurs de comparaison Bash && et ||, utilisés à l'intérieur de double crochets.
[[ condition1 && condition2 ]]
Les opérateurs -o et -a fonctionnent avec la commande test ou à l'intérieur de simples crochets de test.
if [ "$exp1" -a "$exp2" ]
Référez-vous à l'Exemple 8.3, « Tests de conditions composées en utilisant && et || », à l'Exemple 26.16, « Simuler un tableau à deux dimensions, puis son test » et à l'Exemple A.31, « Chasse aux spammeurs » pour voir des opérateurs de comparaison composée en action.
[31] Comme S.C. l'a indiqué, dans un test composé, mettre la variable chaîne de caractères entre quotes pourrait ne pas suffire. [ -n "$chaine" -o "$a" = "$b" ] peut causer une erreur avec certaines versions de Bash si $chaine est vide. La façon la plus sûre est d'ajouter un caractère supplémentaire aux variables potentiellement vides, [ "x$chaine" != x -o "x$a" = "x$b" ] (les « x » sont annulés).