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.