Commandes Bash : Chapitre sur Trap, controle du flux

Intro:

La commande trap permet d’exécuter des actions spécifiques lorsqu’un signal est capturé ou lorsqu’un événement particulier survient dans un script Bash.

—

Principe :

  • trap intercepte un signal (par ex. : SIGINT pour Ctrl+C) ou un événement (par ex. : ERR pour une erreur) et exécute une commande ou un bloc de code.

  • Cela permet de gérer les interruptions, d’effectuer des nettoyages ou de réagir à des erreurs.

Syntaxe :

trap 'commande' signal
  • `commande` : La commande ou le code à exécuter lors de la réception du signal.

  • `signal` : Le signal ou l’événement à surveiller (par exemple, EXIT, ERR, SIGINT).

—

Capture des erreurs avec `ERR` :

  • trap ERR détecte automatiquement les erreurs des commandes qui retournent un code de sortie non nul.

  • Lorsque ERR est déclenché, trap exécute la commande ou le bloc défini.

Exemple simplifié :

trap 'echo "Une erreur est survenue."' ERR

echo "Début du script."
cp fichier_inexistant.txt /tmp  # Cette commande échoue
echo "Cette ligne est exécutée si set -e n'est pas activé."

Explication :

  1. Déclaration du `trap` :

    • Dès qu’une commande échoue, trap ERR exécute echo “Une erreur est survenue.”.

  2. Échec de la commande `cp` :

    • cp tente de copier un fichier inexistant, ce qui provoque une erreur (code de sortie non nul).

    • L’événement ERR est déclenché, et le message d’erreur défini dans trap est affiché.

  3. Conséquence :

    • Si set -e est activé, le script s’arrête après l’exécution de la commande trap.

    • Si set -e n’est pas activé, la commande suivante continue de s’exécuter.

—

Gestion des signaux système :

  • trap peut capturer des signaux système spécifiques pour gérer des interruptions extérieures au script.

    • `SIGINT` : Interruption manuelle via Ctrl+C.

    • `SIGTERM` : Arrêt demandé par un autre processus.

    • `SIGHUP` : Déconnexion de la session terminal.

Exemple : Interception de Ctrl+C (`SIGINT`)

trap 'echo "Interruption détectée. Le script ne sera pas interrompu."' SIGINT

while true; do
    echo "Travail en cours..."
    sleep 1
done

Explication :

  1. Lorsque l’utilisateur appuie sur Ctrl+C, le signal SIGINT est intercepté.

  2. Au lieu de stopper le script, le message “Interruption détectée. Le script ne sera pas interrompu.” est affiché.

  3. La boucle continue de s’exécuter normalement.

—

Nettoyage avec `EXIT` :

  • trap EXIT exécute une commande ou un bloc de code à la fin de l’exécution du script.

  • Cela s’applique même si le script se termine suite à une erreur ou un exit.

Exemple : Gestion de fichiers temporaires

trap 'rm -rf /tmp/tempfile; echo "Nettoyage terminé."' EXIT

echo "Création d’un fichier temporaire."
touch /tmp/tempfile
echo "Fichier temporaire créé : /tmp/tempfile"
echo "Fin du script."

Explication :

  1. Déclaration du `trap` :

    • À la fin du script (signal EXIT), la commande rm -rf /tmp/tempfile est exécutée pour supprimer le fichier temporaire.

  2. Création du fichier temporaire :

    • Le script crée un fichier temporaire avec touch /tmp/tempfile.

  3. Nettoyage automatique :

    • Une fois le script terminé, le trap EXIT supprime le fichier temporaire et affiche le message “Nettoyage terminé.”.

—

Sous-shells et `trap ERR` :

  • trap ERR ne capture pas les erreurs dans les sous-shells. Les commandes exécutées dans des sous-shells (par exemple, avec $(…) ou (commandes)) ne déclenchent pas ERR.

Exemple :

trap 'echo "Erreur détectée."' ERR
echo $(ls fichier_inexistant.txt)  # Pas capturé par trap ERR

Explication :

  1. ls fichier_inexistant.txt échoue dans un sous-shell (car il est dans $()).

  2. trap ERR ne détecte pas cette erreur.

—

Blocs conditionnels et `trap ERR` :

  • Les erreurs dans des blocs conditionnels (comme if ou while) ne déclenchent pas trap ERR, car ces contextes évaluent volontairement l’état de la commande.

Exemple :

trap 'echo "Erreur capturée."' ERR

if ls fichier_inexistant.txt; then
    echo "Fichier trouvé."
fi  # L'erreur de ls n'est pas capturée par trap ERR

Explication :

  1. ls fichier_inexistant.txt échoue, mais l’erreur est évaluée dans le contexte du if.

  2. trap ERR n’est pas déclenché dans ce cas.

—

Résumé des signaux courants :

  • `ERR` : Détecte les erreurs des commandes Bash (hors sous-shells ou conditionnels).

  • `EXIT` : Exécute une commande à la fin du script.

  • `SIGINT` : Intercepte une interruption par Ctrl+C.

  • `SIGTERM` : Capture une demande d’arrêt envoyée par un processus.

  • `SIGHUP` : Réagit à une déconnexion du terminal.