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 :
Déclaration du `trap` :
Dès qu’une commande échoue, trap ERR exécute echo “Une erreur est survenue.”.
É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é.
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 :
Lorsque l’utilisateur appuie sur Ctrl+C, le signal SIGINT est intercepté.
Au lieu de stopper le script, le message “Interruption détectée. Le script ne sera pas interrompu.” est affiché.
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 :
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.
Création du fichier temporaire :
Le script crée un fichier temporaire avec touch /tmp/tempfile.
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 :
ls fichier_inexistant.txt échoue dans un sous-shell (car il est dans $()).
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 :
ls fichier_inexistant.txt échoue, mais l’erreur est évaluée dans le contexte du if.
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.