if
Quelle condition ou commande faut-il évaluer ?
Impact décision : Le bloc continue selon le statut de retour.
Guide pratique pour écrire des conditions Bash fiables, lisibles et faciles à déboguer.
Les conditions Bash deviennent simples quand on arrête de les apprendre comme une suite de symboles. Un if sert à poser une question, then lance le bloc si la réponse est vraie, else prévoit l'autre cas, elif ajoute une étape intermédiaire, et fi ferme la structure.
La difficulté vient surtout des détails : espaces autour des crochets, guillemets, choix entre [ ] et [[ ]], comparaisons numériques, tests de fichiers et enchaînement avec && ou ||. Une condition Bash fiable n'est pas spectaculaire. Elle est lisible, testable et adaptée au type de donnée que le script manipule.
Une condition Bash commence par if, évalue une commande ou une expression, puis exécute le bloc placé après then si le statut de retour vaut zéro. C'est une nuance importante : Bash ne raisonne pas seulement en vrai ou faux abstrait, il lit surtout le code de sortie de ce qui vient d'être exécuté.
if [ -f "$file" ]; then
echo "Le fichier existe"
else
echo "Fichier introuvable"
fi
Dans cet exemple, -f teste l'existence d'un fichier régulier. Les espaces autour des crochets sont obligatoires, parce que [ est une commande de test. Sans espaces, Bash ne lit plus la même chose. Les guillemets autour de $file évitent aussi qu'un chemin avec espace casse la condition.
Le bloc else n'est pas obligatoire. Il devient utile quand le script doit prendre une vraie décision binaire : continuer ou arrêter, utiliser un fichier ou afficher une erreur, traiter une entrée ou refuser une valeur.
Chaque mot-clé a un rôle simple. Le script devient plus lisible quand ce rôle reste clair.
Quelle condition ou commande faut-il évaluer ?
Impact décision : Le bloc continue selon le statut de retour.
Que faire si le test réussit ?
Impact décision : C est le chemin principal du script.
Que faire si le test échoue ?
Impact décision : Utile pour les erreurs ou les valeurs par défaut.
Où se termine la structure ?
Impact décision : Oublier fi est une erreur de syntaxe classique.
elif sert à tester plusieurs cas dans un ordre précis. Dès qu'un cas est vrai, Bash exécute le bloc correspondant et ignore les suivants. C'est plus propre qu'une succession de if séparés quand les cas sont exclusifs.
if [ "$env" = "prod" ]; then
echo "Déploiement prudent"
elif [ "$env" = "staging" ]; then
echo "Tests intermédiaires"
else
echo "Environnement local"
fi
Utilisez elif pour des niveaux, des modes, des statuts ou des valeurs alternatives : environnement, type de fichier, profil utilisateur, état de service, argument de commande. Si plusieurs blocs peuvent être vrais en même temps et doivent tous s'exécuter, gardez plutôt plusieurs if séparés.
Dans Bash, [ ] correspond à la commande test. Elle reste utile, classique et plus portable. [[ ]] est une construction Bash plus confortable : elle gère mieux certains tests de chaînes, les motifs et limite plusieurs pièges liés au découpage des mots.
Dans un script qui assume Bash, [[ ]] est souvent le choix le plus lisible pour les chaînes. Dans un script qui doit fonctionner avec sh ou un shell minimal, restez avec [ ] et soyez strict sur les guillemets.
| Besoin | Forme courante | Remarque |
|---|---|---|
| Tester un fichier | [ -f "$file" ] | Portable et très lisible. |
| Comparer une chaîne | [[ "$name" == "admin" ]] | Confortable en Bash. |
| Tester un motif | [[ "$file" == *.log ]] | Le motif fonctionne naturellement avec [[ ]]. |
| Faire du numérique | (( count > 10 )) | Lisible pour les entiers et calculs simples. |
Une grande source d'erreurs vient du mélange entre comparaison numérique et comparaison textuelle. Avec [ ], les entiers utilisent des opérateurs comme -eq, -ne, -lt, -le, -gt ou -ge. Les chaînes utilisent plutôt =, !=, -z ou -n.
if [ "$count" -gt 10 ]; then
echo "Plus de dix éléments"
fi
if [ -z "$name" ]; then
echo "Nom manquant"
fi
Pour les fichiers, les tests les plus fréquents sont -e pour une existence quelconque, -f pour un fichier régulier, -d pour un dossier, -r pour la lecture, -w pour l'écriture et -x pour l'exécution. Ces tests rendent les scripts plus prévisibles que des commandes lancées sans vérification.
Le bon opérateur dépend du type de donnée, pas de la phrase que vous avez en tête.
-gt, -eq
À utiliser avec [ ] pour comparer des entiers.
=, !=, -z
Pour une valeur textuelle, vide ou non vide.
-f, -d, -e
Pour vérifier existence, type et accès avant traitement.
(( ... ))
Plus naturel pour des conditions arithmétiques Bash.
Prenons un cas courant : un script doit lire un fichier de configuration. Il ne doit pas seulement vérifier que le chemin existe. Il doit confirmer que c'est bien un fichier, qu'il est lisible, puis choisir quoi faire si l'argument est absent. Ce type de contrôle paraît banal, mais il évite beaucoup d'automatisations fragiles.
config_file="$1"
if [ -z "$config_file" ]; then
echo "Usage: $0 config.yml" >&2
exit 1
elif [ ! -f "$config_file" ]; then
echo "Fichier introuvable: $config_file" >&2
exit 1
elif [ ! -r "$config_file" ]; then
echo "Fichier non lisible: $config_file" >&2
exit 1
else
echo "Configuration prête"
fi
La logique est volontairement progressive. On teste d'abord l'argument manquant, puis le type de fichier, puis le droit de lecture. Chaque erreur a un message différent et sort avec exit 1. Le bloc else ne cache pas une erreur : il marque le seul cas où le script peut continuer.
Cette façon d'écrire paraît plus longue qu'une condition compacte, mais elle rend le script maintenable. Si un collègue lance l'automatisation avec un mauvais chemin, il comprend immédiatement ce qui manque. En production, un message d'erreur précis vaut souvent mieux qu'un raccourci élégant.
Vous pouvez combiner plusieurs tests avec && pour un ET logique ou || pour un OU logique. La règle pratique : si la condition tient sur une ligne et reste claire, elle est acceptable. Si vous devez relire trois fois, découpez-la en variables intermédiaires ou en fonctions.
if [[ -f "$file" && "$file" == *.log ]]; then
echo "Fichier log valide"
fi
Pour les scripts maintenus par plusieurs personnes, la lisibilité vaut souvent mieux qu'une condition très compacte. Donnez un nom au résultat quand il porte une intention métier : is_config_ready, has_valid_backup, should_deploy. Une condition Bash doit exprimer une décision claire, pas seulement une prouesse de syntaxe.
Dans un vrai script, une condition ne vit pas seule. Elle prépare souvent une action risquée : supprimer un fichier, lancer une sauvegarde, redémarrer un service, publier un build ou modifier une configuration. Plus l'action est sensible, plus la condition doit être explicite.
Ajoutez donc des sorties claires. Utilisez >&2 pour écrire les erreurs dans la sortie d'erreur, exit 1 quand le script doit s'arrêter, et des noms de variables qui décrivent l'intention. Une condition qui vérifie un prérequis critique doit dire ce qui manque, pas seulement échouer silencieusement.
Pensez aussi aux entrées utilisateur. Un argument vide, un chemin relatif, un fichier avec espace, une valeur numérique absente ou un mode inconnu sont des cas normaux, pas des exceptions rares. Les tester au début du script donne un code plus simple ensuite.
La première erreur est d'oublier les espaces : [ "$x" = "ok" ] fonctionne, ["$x"="ok"] ne signifie pas la même chose. La deuxième est d'oublier les guillemets autour des variables dans les tests portables. Une variable vide ou contenant un espace peut alors produire un résultat inattendu.
La troisième erreur est de comparer des nombres comme des chaînes, ou l'inverse. La quatrième est de supposer qu'une commande réussit sans lire son code de sortie. Bash prend les décisions sur le statut de retour : zéro signifie succès, autre chose signifie échec. C'est ce principe qui permet d'écrire des conditions sur des commandes réelles.
Enfin, méfiez-vous des conditions qui masquent les erreurs. Si un fichier est obligatoire, le bon script doit afficher un message clair et sortir proprement. Un else silencieux crée des automatisations difficiles à diagnostiquer.
En Bash, toute commande peut servir de condition. Vous n'êtes pas obligé d'utiliser uniquement des crochets. Par exemple, un grep -q peut tester la présence d'un motif, et une commande de sauvegarde peut déclencher une alerte si elle échoue. Cette logique est puissante, mais elle demande de connaître le comportement de la commande appelée.
if grep -q "ERROR" app.log; then
echo "Des erreurs sont présentes"
fi
Ce style est lisible quand la commande est claire et que son code de sortie est fiable. Si la commande peut échouer pour plusieurs raisons différentes, ajoutez un message ou un traitement d'erreur plus explicite.
Ces points évitent la majorité des erreurs de scripts.
Commencez par afficher les variables que la condition utilise. Beaucoup de bugs viennent d'une valeur vide, d'un espace final ou d'un chemin différent de ce que vous imaginez. Ensuite, testez la syntaxe avec bash -n script.sh. Cette commande ne lance pas le script, elle vérifie seulement les erreurs de syntaxe.
Pour suivre l'exécution, utilisez bash -x script.sh ou activez temporairement set -x. Vous verrez les commandes évaluées par Bash. C'est souvent plus efficace que de deviner pourquoi un elif n'est jamais atteint.
Quand le script devient important, ajoutez des messages d'erreur explicites et utilisez exit 1 pour signaler un échec. Une bonne condition ne se contente pas de choisir un chemin. Elle aide aussi la personne qui maintient le script à comprendre ce qui a été refusé.
Pour écrire des conditions Bash fiables, partez du type de question : fichier, chaîne, nombre, commande ou combinaison. Choisissez ensuite la syntaxe adaptée : [ ], [[ ]] ou (( )). Ajoutez elif quand les cas sont multiples et exclusifs, puis gardez un else clair pour les erreurs ou les valeurs par défaut.
La maîtrise vient surtout de la régularité : guillemets, espaces, bons opérateurs, tests simples et débogage avec bash -n ou bash -x. Une condition lisible aujourd'hui sera encore compréhensible dans six mois, au moment où le script cassera en production.
La syntaxe des constructions conditionnelles et des expressions de test est cadrée par le manuel GNU Bash.
À lire aussi
Un condensé de veille télécom, cloud, sécurité et outils numériques pour décider plus vite, sans bruit inutile.
Aucun spam. Désinscription en un clic.