Aller au contenu principal

Les conditions : if, else et les tests

Notions théoriques

Le code de retour

Chaque commande Linux, en se terminant, renvoie un code de retour : 0 signifie qu'elle a réussi, toute autre valeur (1 à 255) signifie qu'elle a échoué. Ce code est disponible juste après dans la variable spéciale $?.

ls /tmp
echo $? # 0 : la commande a réussi

ls /nexistepas
echo $? # une valeur différente de 0 : la commande a échoué

C'est ce code de retour que Bash utilise pour évaluer une condition ifpas un booléen « vrai/faux » comme dans d'autres langages.

La structure if

if commande; then
# exécuté si commande a réussi (code de retour 0)
echo "OK"
fi

Tester une expression avec test ou [ ]

Pour tester une condition (et non le résultat d'une commande), on utilise la commande test, le plus souvent écrite sous sa forme équivalente avec des crochets :

if [ "$age" -ge 18 ]; then
echo "Majeur"
fi
attention

Les espaces à l'intérieur des crochets sont obligatoires : [ "$age" -ge 18 ] et non ["$age" -ge 18] ou [ "$age" -ge 18]. Sans ces espaces, Bash interprète mal la commande et affiche une erreur de syntaxe.

Tests sur les fichiers

TestVrai si...
-e fichierle fichier (ou dossier) existe
-f fichierc'est un fichier régulier
-d dossierc'est un dossier
-r fichierle fichier est lisible
-w fichierle fichier est modifiable
-x fichierle fichier est exécutable

Tests sur les chaînes de caractères

TestVrai si...
"$a" = "$b"les deux chaînes sont égales
"$a" != "$b"les deux chaînes sont différentes
-z "$a"la chaîne est vide
-n "$a"la chaîne n'est pas vide
if [ -z "$1" ]; then
echo "Aucun argument fourni"
fi
info

Les guillemets autour de "$1" évitent une erreur si l'argument n'est pas fourni du tout : sans guillemets, [ -z $1 ] deviendrait [ -z ], ce qui provoque une erreur de syntaxe.

Tests numériques

TestSignification
-eqégal à (equal)
-nedifférent de (not equal)
-ltinférieur à (less than)
-leinférieur ou égal (less or equal)
-gtsupérieur à (greater than)
-gesupérieur ou égal (greater or equal)
attention

Piège classique : = compare des chaînes de caractères, -eq compare des nombres. [ "$note" = 20 ] et [ "$note" -eq 20 ] peuvent donner des résultats différents selon le contenu de $note. Pour comparer des nombres, utilisez toujours -eq, -lt, -gt, etc.

if / elif / else

if [ "$note" -ge 16 ]; then
echo "Très bien"
elif [ "$note" -ge 10 ]; then
echo "Passable"
else
echo "Insuffisant"
fi

Combiner des tests

  • ! pour la négation : if [ ! -d "$dossier" ]
  • && (ET) et || (OU) entre deux tests : if [ -d "$dossier" ] && [ -r "$dossier" ]

Quitter un script avec un code explicite

exit 0 # tout s'est bien passé
exit 1 # une erreur s'est produite

Terminer un script avec exit et un code de retour explicite permet à un autre script (ou à une tâche planifiée) de savoir si l'exécution a réussi.

info

Vous croiserez aussi la syntaxe [[ expression ]], spécifique à Bash et un peu plus permissive que [ ] (elle évite par exemple certains pièges de quoting). Nous l'utiliserons davantage au niveau 2 ; pour l'instant, [ ] suffit et fonctionne dans tous les shells.

Exemple pratique

#!/bin/bash
# Script : verif_sauvegarde.sh
# Rôle : vérifier qu'un dossier peut être sauvegardé

if [ $# -eq 0 ]; then
echo "Usage : $0 <dossier>"
exit 1
fi

dossier="$1"

if [ ! -d "$dossier" ]; then
echo "Erreur : $dossier n'est pas un dossier valide"
exit 1
elif [ ! -r "$dossier" ]; then
echo "Erreur : $dossier n'est pas lisible"
exit 1
else
echo "$dossier est prêt à être sauvegardé"
exit 0
fi

Test de mémorisation/compréhension


Que vaut $? après une commande qui s'est correctement exécutée ?


Quel test vérifie l'existence d'un répertoire ?


Pourquoi [$# -eq 0] provoque-t-il une erreur de syntaxe ?


Quel opérateur compare deux nombres en Bash ?


TP pour réfléchir et résoudre des problèmes

Nous poursuivons sauvegarde.sh en le sécurisant : il doit vérifier ses entrées avant d'agir.

Étape 1 — Refuser l'exécution sans argument


Bonne pratique - Sortir tôt

Vérifiez les cas d'erreur en premier et sortez immédiatement avec exit 1 plutôt que d'imbriquer tout le reste du script dans un grand if. Le code principal reste ainsi lisible, sans indentation excessive.

Étape 2 — Vérifier que le dossier existe


Bonne pratique - Toujours vérifier ses entrées

Ne faites jamais confiance à un argument sans le vérifier, surtout avant une action qui modifie ou supprime des fichiers. Un dossier inexistant ou mal orthographié doit être détecté avant, pas provoquer une erreur incompréhensible plus loin.

Étape 3 — Créer le dossier de destination s'il n'existe pas


Bonne pratique - Un script idempotent

Un script est dit idempotent quand on peut le relancer plusieurs fois sans effet indésirable. Vérifier l'existence d'un dossier avant de le créer (plutôt que de faire mkdir sans condition) rend le script plus robuste face à une seconde exécution.

Étape 4 — Vérifier le résultat de la sauvegarde


Bonne pratique - Ne jamais supposer qu'une commande a réussi

Un script qui ne vérifie jamais le résultat de ses commandes peut échouer en silence : il continue comme si tout allait bien alors qu'une étape critique a échoué. Vérifier $? (ou tester directement la commande dans le if) évite ce piège.

📌 Une solution