E-NO Logo
EN FR
Bash troubleshooting 8 Min Read

Bash troubleshooting avec des exemples pratiques : guide d'implémentation

calendar_today Published: 2026-07-17
update Last Updated: 2026-07-17
analytics SEO Efficiency: 100%
Technical guide illustration for Bash troubleshooting avec des exemples pratiques : guide d'implémentation.

Introduction

Bash est la colle qui tient ensemble de nombreux jobs de build, de release et d'exploitation. Quand cela échoue, le rayon d'action peut être important. Ce guide est une référence hands-on pour diagnostiquer et corriger des problèmes Bash avec des extraits prêts à copier-coller. Vous y trouverez un workflow simple, quels Bash logs capturer, des Bash commands sûres qui évitent la perte de données, et des schémas de récupération pas à pas que vous pouvez exécuter localement, dans Docker et Docker Compose, et à l'intérieur de pods Kubernetes. Les mots-clés utiles (Bash troubleshooting, Bash errors, Bash recovery) sont utilisés naturellement tout au long du guide.

Aperçu du workflow

Suivez ce flux reproductible, du symptôme au correctif validé :

  1. Capturer le symptôme
  • Notez la commande exacte, ses arguments, le répertoire courant et le code de sortie : echo $?.
  • Sauvegardez stderr et stdout séparément : cmd 1>out.log 2>err.log.
  • Enregistrez les versions : bash --version, printf '%s\n' "$BASH_VERSION".
  1. Réduire l'échec
  • Réduisez le script au plus petit extrait qui échoue encore.
  • Remplacez les dépendances externes par des fakes ou des fixtures.
  1. Tracer et journaliser
  • Activez le tracing uniquement autour des lignes suspectes :
  {
    set -x
    # bloc suspect
    do_thing
    set +x
  } 2>trace.log
  • Ajoutez des timestamps pour les étapes lentes :
  export PS4='+ ${EPOCHREALTIME} ${BASH_SOURCE}:${LINENO}: '
  1. Exécuter des vérifications de cause racine
  • Vérifiez PATH, les guillemets, les permissions, les fins de ligne et le comportement des pipelines.
  1. Appliquer une correction sûre
  • Utilisez des options non destructives, des dry-runs et des fichiers temporaires.
  1. Prouver et documenter
  • Rejouez le repro minimal et le script original.
  • Ajoutez un test ou un exemple pour éviter la régression.

Collecte des logs

De bons logs répondent à : quoi a échoué, où et pourquoi.

  • Capture de base
  # Code de sortie et stderr
  failing_cmd 1>stdout.log 2>stderr.log; echo $? >exit.code

  # Trace complète dans un descripteur séparé pour ne pas mélanger avec la sortie du programme
  exec {XTRACE_FD}>trace.log
  export BASH_XTRACEFD=$XTRACE_FD
  export PS4='+ ${EPOCHREALTIME} ${BASH_SOURCE}:${LINENO}: '
  set -x
  failing_cmd
  set +x
  exec {XTRACE_FD}>&-
  • Garder les secrets hors des logs
  set +x  # désactiver le tracing autour des secrets
  token="${TOKEN:?missing TOKEN}"
  set -x
  • Logs de conteneur et de cluster
  • Docker : docker logs <container> 2>&1 | tee container.log
  • Compose : docker compose logs svc -f
  • Kubernetes : kubectl logs pod/my-pod -c my-container --timestamps
  • Instantané d'environnement (éviter les secrets)
  ( env | grep -Ev 'KEY|SECRET|TOKEN|PASS' ) | sort >env.snapshot

Vérifications de cause racine

Ciblez d'abord les classes d'échecs courantes avant de deviner.

  1. PATH et résolution de commande
which mycmd || type -a mycmd || echo 'missing'
hash -r  # vider le cache de hachage de Bash si les binaires ont bougé
printf '%s\n' "$PATH" | tr ':' '\n'
  1. Shebang et différences de shell
head -1 script.sh  # devrait être : #!/usr/bin/env bash
bash -n script.sh  # vérification de syntaxe
# Certaines distros font /bin/sh -> dash ; forcer bash si nécessaire
bash script.sh
  1. Permissions et exécutables
chmod +x script.sh
file script.sh  # vérifier la présence de CRLF
# Si CRLF détecté, normaliser :
dos2unix script.sh  # ou : sed -i 's/\r$//' script.sh
  1. Guillemets et globbing
# Expansion de variable sûre
echo "$var"
# Désactiver le globbing lors de l'expansion d'entrées utilisateur
set -f; printf '%s\n' $user_input; set +f
# Plus sûr : toujours citer
printf '%s\n' "$user_input"
  1. Pipelines et codes de sortie
set -o pipefail  # échouer si une commande du pipeline échoue
# Capturer le statut du pipeline
foo | bar | baz; ec=$?; echo "pipeline exit=$ec"
# Si un non-match de grep est acceptable :
grep -q pattern file || true
  1. Variables non liées et valeurs par défaut
set -u   # traiter les variables non définies comme des erreurs
# Fournir des valeurs par défaut ou des erreurs franches
name="${NAME:-anonymous}"
api="${API_URL:?API_URL is required}"
  1. Boucles sûres pour stdin
# Traiter des lignes en préservant les espaces et sans globbing
while IFS= read -r line; do
  printf 'line: %s\n' "$line"
done < input.txt
  1. Fichiers temporaires et conditions de concurrence
f=$(mktemp) || exit 1
trap 'rm -f "$f"' EXIT
# utiliser "$f" en toute sécurité ici

Commandes sûres

Préférez les opérations non destructives pendant la récupération.

  • Dry-runs et no-clobber
rsync -av --dry-run src/ dst/
cp -an src/ dst/   # -n no-clobber, -a préservation
mv -i old new      # -i demande de confirmation
rm -i file         # confirmer avant de supprimer
  • Sauvegardes et points de contrôle
cp -a dir "dir.bak.$(date +%Y%m%d-%H%M%S)"
  • Garde-fous
set -euo pipefail  # attention : modifie la sémantique d'échec
# Réduire la portée à un bloc
do_safe() {
  set -euo pipefail
  "$@"
}
  • Limitation de débit et timeouts
timeout 10s long_running || echo 'timed out'

Récupération pas à pas

Voici des playbooks pratiques à adapter.

1) Commande introuvable ou mauvais binaire

Symptômes : command not found ou une version inattendue s'exécute.

Vérifications

type -a tool
printf '%s\n' "$PATH" | tr ':' '\n'
hash -r

Correctifs

  • Installer ou ajuster PATH dans le script : export PATH=/opt/tool/bin:$PATH.
  • Utiliser des chemins absolus pour les binaires critiques.
  • En conteneur, placer la dépendance dans l'image ou l'installer au démarrage.

2) Crash de variable non liée

Symptômes : unbound variable avec set -u.

Vérifications

set -u
: "${NAME:?NAME is required}"

Correctifs

  • Fournir des valeurs par défaut ou des échecs explicites :
  NAME="${NAME:-guest}"
  API_URL="${API_URL:?required}"

3) Échec masqué par un pipeline

Symptômes : la dernière commande réussit mais une étape amont a échoué.

Vérification et correctif

set -o pipefail
foo | bar | baz

Si un retour non-zéro de grep sans correspondance est acceptable, ajoutez || true.

4) Problème de permission ou de shebang

Symptômes : Permission denied ou le script tourne sous sh au lieu de Bash.

Vérifications et correctifs

chmod +x script.sh
sed -n '1p' script.sh  # attendre #!/usr/bin/env bash
bash -n script.sh

5) Fins de ligne CRLF cassent l'exécution

Symptômes : apparition de ^M ou scripts qui échouent dans des conteneurs Linux.

Correctif

file script.sh
dos2unix script.sh  # ou sed -i 's/\r$//' script.sh

6) Bug de guillemets et expansion inattendue

Symptômes : noms de fichiers avec espaces qui cassent les boucles ou les cibles de rm.

Patron de correctif

# Toujours citer les expansions
rm -- "$file"
# find + xargs en toute sécurité
find . -type f -name '*.log' -print0 | xargs -0 rm -f --

7) Différences cron vs interactif

Symptômes : un script réussit en shell, échoue sous cron ou un job runner.

Vérifications

# Cron a un environnement minimal
( env | sort ) >interactive.env
( env -i bash -lc 'env' | sort ) >isolated.env
diff -u interactive.env isolated.env || true

Correctifs

  • Définir PATH explicitement dans le script.
  • Utiliser des chemins absolus pour les fichiers et binaires.
  • Sourcer un profil connu si requis, ou exporter les variables nécessaires dans l'entrée crontab.

Spécificités Docker et Docker Compose

  • Reproduire à l'intérieur de la même image
  docker run --rm -it -v "$PWD":/work -w /work myimg bash -lc './script.sh'
  docker exec -it mycontainer bash -lc 'type -a tool && ./script.sh'
  • Vérifier propriétaire et permissions après des bind mounts.
  • Normaliser les fins de ligne sur l'hôte avant de builder l'image.
  • Shell sur un service Compose
  docker compose run --rm svc bash -lc 'set -euxo pipefail; ./script.sh'

Spécificités Kubernetes (Pods, Ingress, Secrets)

  • Exec dans le conteneur avec le bon shell
  kubectl exec -it deploy/app -c app -- bash -lc 'type -a bash || cat /etc/os-release'
  • Logs et redémarrages
  kubectl logs deploy/app -c app --timestamps --previous
  • Config et secrets
  # Inspecter les fichiers montés sans afficher les valeurs dans l'historique
  ls -l /etc/config /etc/secret
  stat /etc/secret/*
  # Éviter le tracing des expansions de secrets
  set +x; KEY="${API_KEY:?missing}"; set -x
  • Vérifications réseau utiles à Ingress et services
  curl -sv http://svc.namespace.svc.cluster.local:8080/health || true
  getent hosts example.com
  nc -zv example.com 443 || true

Plan pilote local

Gardez votre première implémentation petite, mesurable et simple à inspecter localement.

  1. Choisir 3 échecs fréquents
  • Exemple : variable non liée, lignes CRLF et échec masqué de pipeline.
  1. Créer des repros minimaux
# repro-unbound.sh
set -u; echo "Hello $NAME"

# repro-crlf.sh (volontairement CRLF)
printf 'echo win\r\n' > repro-crlf.sh

# repro-pipe.sh
false | grep x
  1. Ajouter un wrapper de trace et logs
run_traced() {
  exec {XTRACE_FD}>trace.log
  export BASH_XTRACEFD=$XTRACE_FD
  export PS4='+ ${EPOCHREALTIME} ${BASH_SOURCE}:${LINENO}: '
  set -x; "$@"; ec=$?; set +x
  exec {XTRACE_FD}>&-
  return "$ec"
}
run_traced bash repro-unbound.sh || true
  1. Mesurer le temps de correction
  • Mesurez le temps nécessaire pour identifier et corriger avant et après l'ajout du wrapper et des vérifications.
  • Un timer simple : time bash repro-unbound.sh.
  1. Étendre aux conteneurs et aux clusters
  • Une fois le pilote local stable, reproduisez dans votre image Docker et dans un pod Kubernetes, puis appliquez les mêmes vérifications et wrappers.

Conclusion

Le Bash troubleshooting s'accélère quand vous suivez un workflow clair, capturez les bons Bash logs, utilisez des Bash commands de récupération sûres et appliquez des playbooks éprouvés pour les échecs courants. Commencez par un petit pilote local, mesurez l'impact, puis étendez les mêmes schémas à Docker, Docker Compose et Kubernetes (Ingress, Secrets compris). Continuez d'enrichir vos exemples et snippets pour rendre les incidents futurs prévisibles et à faible risque.

Article Quality Score

Reader usefulness 100%
  • check_circle Reader-ready guide
  • check_circle Practical examples included
  • check_circle Clean SEO article URL