7.3. Opérateurs de comparaison (binaire)

comparaison d'entiers

-eq

est égal à

if [ "$a" -eq "$b" ]

-ne

n'est pas égal à

if [ "$a" -ne "$b" ]

-gt

est plus grand que

if ["$a" -gt "$b" ]

-ge

est plus grand ou égal à

if [ "$a" -ge "$b" ]

-lt

est plus petit que

if [ "$a" -lt "$b" ]

-le

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

=

est égal à

if [ "$a" = "$b" ]

==

est égal à

if [ "$a" == "$b" ]

Ceci est un synonyme de =.

[[ $a == z* ]]    # vrai si $a commence avec un "z" (reconnaissance de modèles)
[[ $a == "z*" ]]  # vrai si $a est égal à z*

[ $a == z* ]      # decoupage de mots et file globbing ont lieu
[ "$a" == "z*" ]  # vrai si $a est égal à z*

# Merci, S.C.

!=

n'est pas égal à

if [ "$a" != "$b" ]

Cet opérateur utilise la reconnaissance de modèles à 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 Exemple 26-5 pour une application de cet opérateur de comparaison.

-z

la chaîne de caractères est << vide >>, c'est-à-dire qu'elle a une taille nulle

-n

la chaîne de caractères n'est pas << vide >>.

Attention

Attention : Le test -n nécessite absolument que la chaîne de caractères soit entre quotes à l'intérieur des crochets de test. Utiliser une chaîne sans quotes avec ! -z, voire simplement la chaîne sans quote à l'intérieur des crochets (voir Exemple 7-6) fonctionne habituellement, néanmoins, c'est une pratique peu sûre. Placez toujours vos chaînes de caractères à tester entre quotes. [1]

Exemple 7-5. comparaisons arithmétiques 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.
#  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, ni "-ne" ni "!=" ne fonctionnent.

echo

exit 0

Exemple 7-6. vérification si une chaîne 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é, 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 Stephane Chazelas le dit,
#    if [ $string 1 ]    a un argument, "]"
#    if [ "$string 1" ]  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. zmost

#!/bin/bash

#Visualiser des fichiers gzip avec 'most'

SANSARGS=65
PASTROUVE=66
NONGZIP=67

if [ $# -eq 0 ] # même effet que:  if [ -z "$1" ]
# $1 peut exister, mais doit être vide:  zmost "" 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 | most

# Utilise le visualisateur de fichier 'most' (similaire à 'less').
# Les dernières versions de 'most' peuvent décompresser les fichiers.
# Peut se substituer à 'more' ou '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.

comparaison composée

-a

et logique

exp1 -a exp2 renvoie vrai si à la fois exp1 et exp2 sont vrais.

-o

ou logique

exp1 -o exp2 renvoie vrai si soit exp1 soit exp2 sont vrais.

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 simple crochets de test.
if [ "$exp1" -a "$exp2" ]

Référez-vous à Exemple 8-3 et à Exemple 26-9 pour voir des opérateurs de comparaison composée en action.

Notes

[1]

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 "$string" -o "$a" = "$b" ] peut causer une erreur avec certaines versions de Bash si $string est vide. La façon la plus sûre est d'ajouter un caractère supplémentaire aux variables potentiellement vides, [ "x$string" != x -o "x$a" = "x$b" ] (les << x >> sont annulés).

>Mail

mail

Envoie ou lit des courriers électroniques.

Ce mail client en ligne de commande et très simpliste fonctionne bien comme commande embarquée dans un script.

Exemple 12-31. Un script qui s'envoie un courrier

#!/bin/sh
# self-mailer.sh: Script vous envoyant un mail.

adr=${1:-`whoami`}     # Par défaut, l'utilisateur courant, si non spécifié.
#  Tapez 'self-mailer.sh wiseguy@superdupergenius.com'
#+ envoie ce script à cette adresse.
#  Tapez juste 'self-mailer.sh' (sans argument) envoie le script à la personne
#+ l'ayant appelé, par exemple bozo@localhost.localdomain.
#
#  Pour plus d'informations sur la construction ${parameter:-default},
#+ voir la section "Substitution de paramètres" du chapitre "Variables
#+ Revisitées."

# ============================================================================
  cat $0 | mail -s "Le script \"`basename $0`\" s'est envoyé lui-même à vous." "$adr"
# ============================================================================

# --------------------------------------------
#  Bonjour du script qui s'envoie par mail.
#  Une personne mal intentionnée a lancé ce script, ce qui a fait que ce mail
#+ vous a été envoyé.
#  Apparemment, certaines personnes n'ont rien de mieux à faire de leur temps.
# --------------------------------------------

echo "Le `date`, le script \"`basename $0`\" vous a été envoyé par mail sur "$adr"."

exit 0
mailto

Similaire à la commande mail, mailto envoie des emails à partir de la ligne de commande ou dans un script. Néanmoins, mailto permet aussi d'envoyer des messages MIME (multimedia).

vacation

Cet utilitaire répond automatiquement aux courriers électroniques que le destinataire est en vacances et temporairement indisponible. Ceci tourne sur le réseau, en conjonction avec sendmail, et n'est pas applicable à un compte POP.

Notes

[1]

Un démon est un processus en tâche de fond non attaché à une session terminal. Les démons réalisent des services désignés soit à des moments précis soit en étant enclenchés par certains événements.

Le mot << démon >> signifie fantôme en grec, et il y a certainement quelque chose de mystérieux, pratiquement surnaturel, sur la façon dont les démons UNIX travaillent silencieusement derrière la scène, réalisant leur différentes tâches.

gzip, ln, patch, tar, tr, bc, xargs. The texinfo documentation on bash, dd, m4, gawk, and sed.

ALIGN="left" VALIGN="top" >PrécédentSommaireSuivantConstructeurs de listesNiveau supérieurFichiers