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.