Quand votre script Bash échoue : une approche systématique de dépannage
Déboguez les échecs de scripts Bash en vérifiant les codes de sortie, en traçant les commandes, en isolant les problèmes d'environnement et en journalisant les exécutions non supervisées.
Quand votre script Bash échoue : une approche systématique de dépannage
Le dépannage d'un échec de script Bash commence par une question : le script a-t-il échoué parce que la commande était erronée, l'environnement était différent ou l'entrée n'était pas celle attendue ? Une routine de débogage reproductible vous évite de deviner lorsqu'une tâche cron, un hook de déploiement ou un script de sauvegarde se brise.
Utilisez les étapes ci-dessous pour lire le signal d'échec, tracer ce que Bash a réellement exécuté et réduire le problème à une commande spécifique.
Phase 1 : Préparation et évaluation initiale
Avant de plonger dans les indicateurs de débogage complexes, assurez-vous d'avoir les éléments fondamentaux en place. Une évaluation initiale structurée permet de gagner un temps considérable.
1. Examinez le message d'erreur et le code de sortie
L'indice le plus immédiat est le message d'erreur rapporté par le shell. Portez une attention particulière au numéro de ligne mentionné, s'il est fourni.
Codes de sortie : En script shell, la variable spéciale
$?contient le statut de sortie de la commande de premier plan la plus récemment exécutée. Une commande réussie renvoie0. Toute valeur non nulle indique un échec.some_command echo "La commande s'est terminée avec le statut : $?" # Si $? est 127, cela signifie souvent "commande introuvable".
2. Vérifiez le mode d'exécution du script
Assurez-vous que le script est exécuté comme prévu, notamment en ce qui concerne l'interpréteur spécifié par la ligne shebang.
Shebang : Commencez toujours votre script par une ligne shebang appropriée pour définir l'interpréteur.
#!/bin/bashest standard, mais#!/usr/bin/env bashest souvent préféré pour la portabilité.Permissions : Confirmez que le script a les permissions d'exécution définies :
chmod +x votre_script.sh
3. Isolez l'environnement d'exécution
Les différences d'environnement sont une source majeure d'échecs intermittents. Testez toujours dans l'environnement où le script est censé s'exécuter, ou confirmez les variables qui diffèrent entre le développement et la production.
Testez directement : Exécutez le script directement en utilisant l'interpréteur, en contournant les éventuels problèmes de PATH si vous l'exécutez simplement par son nom :
/bin/bash ./votre_script.sh
Phase 2 : Activation des indicateurs de débogage Bash
Bash fournit des indicateurs intégrés puissants qui peuvent tracer le flux d'exécution et l'évaluation des variables, ce qui est crucial pour identifier les erreurs de logique ou les expansions inattendues.
1. Les indicateurs de débogage essentiels
Ces indicateurs sont généralement ajoutés à la ligne shebang ou activés/désactivés dans le script à l'aide de set.
| Indicateur | Commande | Objectif |
|---|---|---|
| -n | set -n |
Lit les commandes sans les exécuter (vérification syntaxique uniquement). |
| -v | set -v |
Affiche les lignes d'entrée du shell au fur et à mesure qu'elles sont lues (mode verbeux). |
| -x | set -x |
Affiche les commandes et leurs arguments au fur et à mesure de leur exécution (mode trace). C'est le plus puissant pour les erreurs de logique. |
2. Utilisation du mode trace (set -x)
set -x préfixe la sortie de chaque commande exécutée avec un signe +, montrant exactement ce que Bash interprète, y compris les expansions de variables.
Exemple de traçage :
Considérez un script qui échoue en raison d'un guillemet incorrect :
# Extrait de script original
USER_INPUT="Hello World"
echo $USER_INPUT # Échoue si USER_INPUT contenait des espaces et était passé à une autre commande
Lors de l'exécution avec set -x activé (soit via #!/bin/bash -x soit set -x au début) :
+ USER_INPUT='Hello World'
+ echo Hello World
Hello World
Si vous soupçonnez des problèmes de guillemets, vous pouvez activer le mode trace de manière sélective autour de la section problématique :
set -x
# Commandes qui fonctionnent bien
# Tracez uniquement la section problématique
COMMANDE_QUI_ECHOUE_EN_RAISON_DE_L_EXPANSION
set +x
# Reste du script
Meilleure pratique : Pour déboguer l'ensemble du script, utilisez #!/bin/bash -x ou placez set -x immédiatement après le shebang.
3. Débogage de l'expansion des variables
De nombreux échecs proviennent de la manière dont les variables sont développées (ou non). Utilisez généreusement des guillemets doubles autour des variables ("$VAR") pour éviter la division des mots et l'expansion des globes, mais utilisez le traçage (set -x) pour voir si l'expansion se produit comme prévu.
Si vous voulez voir la valeur littérale d'une variable, y compris les espaces blancs, vous pouvez l'afficher avec echo en l'entourant de guillemets et de délimiteurs :
VAR="a b c"
printf '[%s]\n' "$VAR"
# Sortie : [a b c]
Phase 3 : Gestion des types d'erreurs courants
Une fois les indicateurs de débogage actifs, les erreurs tombent généralement dans des catégories prévisibles.
1. Commande introuvable (code de sortie 127)
Cette erreur, apparaissant souvent sous la forme votre_commande : commande introuvable, indique que le shell ne peut pas localiser l'exécutable.
- Vérifiez PATH : Assurez-vous que le répertoire contenant la commande est listé dans la variable d'environnement
$PATHdans le contexte d'exécution du script. - Utilisez des chemins absolus : En cas de doute, utilisez le chemin complet vers la commande (par exemple,
/usr/bin/curlau lieu de simplementcurl).
2. Erreurs de syntaxe
Celles-ci impliquent souvent des délimiteurs non appariés, une utilisation incorrecte des structures de contrôle (if, for, while), ou des points-virgules/sauts de ligne manquants.
set -n(Pas d'exécution) : Exécuter le script avecset -nforce Bash à tout analyser sans exécuter, révélant souvent immédiatement des crochets non fermés ou des instructionsfi/donemanquantes.Syntaxe conditionnelle : Faites attention à
[[ ... ]]vs[ ... ]. Par exemple, tester l'arithmétique nécessite(( ... ))oulet, et non des structures de test standard.Exemple (Contexte arithmétique) :
# Manière correcte de vérifier si A est supérieur à B A=10 B=5 if (( A > B )); then echo "A est plus grand" fi
3. Problèmes de permissions et d'entrée/sortie
Si le script s'exécute mais échoue lors de l'interaction avec des fichiers ou des processus externes, vérifiez les permissions et les descripteurs de fichiers.
Redirection d'entrée : Si vous redirigez l'entrée depuis un fichier, assurez-vous que ce fichier existe et est lisible.
Redirection de sortie : Vérifiez si le répertoire de destination existe et si l'utilisateur du script a les permissions d'écriture.
Avertissement sur SUDO : Si vous exécutez un script avec
sudo, les variables d'environnement comme$PATHet les configurations spécifiques à l'utilisateur (comme.bashrc) sont souvent réinitialisées ou modifiées. Les commandes qui fonctionnent lorsqu'elles sont exécutées en tant qu'utilisateur normal peuvent échouer soussudoen raison d'un contexte ou de chemins manquants.
Phase 4 : Journalisation et vérifications système
Pour les scripts s'exécutant en arrière-plan (par exemple, via Cron), la sortie directe du terminal n'est pas disponible. Une journalisation robuste est essentielle.
1. Redirection de la sortie pour le débogage
Lors de l'exécution non supervisée, redirigez à la fois la sortie standard (stdout, descripteur 1) et l'erreur standard (stderr, descripteur 2) vers un fichier journal. Les combiner est courant :
# Rediriger toute la sortie vers debug.log
./votre_script.sh >> debug.log 2>&1
Si vous utilisez set -x, la sortie de trace ira dans le même fichier journal, fournissant un enregistrement complet du flux d'exécution et des erreurs.
2. Vérification de la santé du système
Parfois, le script lui-même est correct, mais l'environnement système est le problème :
- Espace disque : Le système manque-t-il d'espace disque (
df -h) ? Cela stoppera les opérations d'écriture. - Mémoire : Vérifiez l'utilisation de la mémoire (
free -m). Une pression mémoire élevée peut entraîner l'échec ou le blocage des commandes externes. - Environnement Cron : Si planifié via Cron, rappelez-vous que les tâches Cron s'exécutent avec un environnement très restreint. Définissez toujours explicitement les variables d'environnement nécessaires en haut du script si elles ne sont pas garanties par la configuration de la tâche Cron.
Gardez le chemin de débogage court
Lorsque votre script Bash échoue, capturez d'abord le code de sortie et l'erreur exacte. Ensuite, confirmez le shebang, les permissions, $PATH, les fichiers d'entrée et le contexte utilisateur. Si la cause est encore floue, activez set -x uniquement autour du bloc suspect et envoyez la sortie non supervisée vers un journal.
Cet ordre maintient le dépannage pratique. Vous passez des preuves les plus claires à la trace la plus détaillée sans vous submerger de bruit.