Capture et gestion des signaux dans les scripts Shell Linux

Dans les systèmes d'exploitation de type Unix comme Linux, les signaux sont utilisés pour la communication entre processus. Un signal est une notification asynchrone envoyée à un processus ou à un thread spécifique au sein du même processus pour informer d'un événement, tel que défini par la norme POSIX.

Lorsqu'un événement survient, le noyau génère un signal et le transmet au processus cible. Les signaux peuvent provenir de diverses sources, y compris d'autres processus, d'erreurs système ou d'actions utilisateur comme l'envoi de Ctrl+C ou Ctrl+Z dans un terminal.

Lorsqu'un processus reçoit un signal, plusieurs réactions sont possibles : il peut l'ignorer, le capturer via un gestionnaire de signaux spécifique, ou exécuter le comportement par défaut associé au signal. Par exemple, le signal SIGTERM (valeur 15) a pour action par défaut de terminer le processus.

Pour lister tous les signaux disponibles avec leurs valeurs, utilisez la commande suivante :

$ kill -l
1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL       5) SIGTRAP
6) SIGABRT      7) SIGBUS       8) SIGFPE       9) SIGKILL     10) SIGUSR1
11) SIGSEGV     12) SIGUSR2     13) SIGPIPE     14) SIGALRM     15) SIGTERM
16) SIGSTKFLT   17) SIGCHLD     18) SIGCONT     19) SIGSTOP     20) SIGTSTP
21) SIGTTIN     22) SIGTTOU     23) SIGURG      24) SIGXCPU     25) SIGXFSZ
26) SIGVTALRM   27) SIGPROF     28) SIGWINCH    29) SIGIO       30) SIGPWR
31) SIGSYS      34) SIGRTMIN    35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+3
38) SIGRTMIN+4  39) SIGRTMIN+5  40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+8
43) SIGRTMIN+9  44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-7
58) SIGRTMAX-6  59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-2
63) SIGRTMAX-1  64) SIGRTMAX

Les valeurs des signaux sont définies dans les fichiers d'en-tête système. Pour obtenir des informations détaillées, consultez la page de manuel :

$ man 7 signal
Signal Comportement par défaut Description Valeur
SIGABRT Génère un fichier core puis termine Signal envoyé par le processus lui-même pour indiquer une terminaison anormale. 6
SIGALRM Termine le processus Signal envoyé lorsqu'une horloge d'alarme expire. 14
SIGBUS Génère un fichier core puis termine Signal envoyé en cas d'erreur de bus, comme un accès mémoire invalide. 10
SIGCHLD Ignoré Signal envoyé lorsqu'un processus enfant change d'état. 20
SIGCONT Reprend l'exécution Signal pour reprendre un processus précédement suspendu. 19
SIGFPE Génère un fichier core puis termine Signal envoyé lors d'une erreur arithmétique, comme une division par zéro. 8
SIGHUP Termine le processus Signal envoyé lorsque le terminal de contrôle se ferme. 8
SIGILL Génère un fichier core puis termine Signal envoyé pour une instruction illégale exécutée. 4
SIGINT Termine le processus Signal envoyé par le terminal pour une interruption utilisateur. 2
SIGKILL Termine immédiatement le processus Signal non capturable pour forcer la terminaison d'un processus. 9
SIGPIPE Termine le processus Signal envoyé lors d'une écriture sur un pipe déconnecté. 13
SIGQUIT Termine le processus Signal envoyé par le terminal pour demander un core dump. 3
SIGSEGV Génère un fichier core puis termine Signal envoyé pour une violation de segmentation mémoire. 11
SIGSTOP Suspend le processus Signal non capturable pour arrêter l'exécution d'un processus. 17
SIGTERRM Termine le processus Signal de demande de terminaison propre. 15
SIGTSTP Suspend le processus Signal envoyé par le terminal pour une suspension interactive. 18
SIGUSR1 Termine le processus Signal défini par l'utilisateur pour des conditions spécifiques. 30
SIGUSR2 Termine le processus Signal défini par l'utilisateur pour des conditions spécifiques. 31

Dans un shell interactif Bash, certains signaux sont gérés différemment. Par exemple, Bash ignore les signaux SIGTERM et SIGQUIT. Lorsqu'un shell reçoit le signal SIGHUP, il peut trensmettre ce signal à ses jobs enfants pour les terminer.

Pour empêcher l'envoi de SIGHUP à un job spécifique, utilisez la commande interne disown. Voici un exemple avec des noms de processus modifiés :

# Exécuter une tâche en arrière-plan
$ calcul_long &
[1] 30561

# Vérifier les jobs actifs
$ jobs -l
[1]+ 30561 Running                 calcul_long &

# Retirer le job 1 de la table des jobs
$ disown %1

# Confirmer la suppression
$ jobs -l

# Vérifier que le processus existe toujours
$ ps -ef | grep calcul_long
utilisateur 30561 30420  0 14:35 pts/1    00:00:00 calcul_long

# Afficher l'identifiant du shell courant
$ echo $$
30420

L'option -h de disown marque un job sans le retirer de la table :

# Exécuter une tâche en arrière-plan
$ traitement_rapide &
[1] 30789

# Lister les jobs
$ jobs -l
[1]+ 30789 Running                 traitement_rapide &

# Marquer le job pour ignorer SIGHUP
$ disown -h %1

# Vérifier l'état du job
$ jobs -l
[1]+ 30789 Running                 traitement_rapide &

Notez que si l'option huponexit du shell est activée via shopt, un shell de connexion interactif enverra SIGHUP à tous les jobs lors de sa fermeture.

Étiquettes: Linux Shell bash signaux processus

Publié le 3 juillet à 20h32