Unix / Linux - Signaux et interruptions

Dans ce chapitre, nous discuterons en détail des signaux et des traps sous Unix.

Les signaux sont des interruptions logicielles envoyées à un programme pour indiquer qu'un événement important s'est produit. Les événements peuvent varier des demandes des utilisateurs aux erreurs d'accès à la mémoire illégales. Certains signaux, tels que le signal d'interruption, indiquent qu'un utilisateur a demandé au programme de faire quelque chose qui n'est pas dans le flux de contrôle habituel.

Le tableau suivant répertorie les signaux courants que vous pourriez rencontrer et que vous souhaitez utiliser dans vos programmes -

Nom du signal Numéro de signal La description
VISION 1 Raccrochage détecté sur le terminal de contrôle ou décès du processus de contrôle
SIGINT 2 Émis si l'utilisateur envoie un signal d'interruption (Ctrl + C)
SIGQUIT 3 Émis si l'utilisateur envoie un signal d'arrêt (Ctrl + D)
SIGFPE 8 Émis si une opération mathématique illégale est tentée
SIGKILL 9 Si un processus reçoit ce signal, il doit s'arrêter immédiatement et n'effectuera aucune opération de nettoyage
SIGALRM 14 Signal de réveil (utilisé pour les minuteries)
SIGTERM 15 Signal de terminaison du logiciel (envoyé par kill par défaut)

Liste des signaux

Il existe un moyen simple de répertorier tous les signaux pris en charge par votre système. Émettez simplement lekill -l commande et il afficherait tous les signaux pris en charge -

$ 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

La liste réelle des signaux varie entre Solaris, HP-UX et Linux.

Actions par défaut

Chaque signal est associé à une action par défaut. L'action par défaut d'un signal est l'action qu'un script ou un programme effectue lorsqu'il reçoit un signal.

Certaines des actions par défaut possibles sont -

  • Terminez le processus.

  • Ignorez le signal.

  • Dump core. Cela crée un fichier appelécore contenant l'image mémoire du processus lorsqu'il a reçu le signal.

  • Arrêtez le processus.

  • Continuez un processus arrêté.

Envoi de signaux

Il existe plusieurs méthodes pour transmettre des signaux à un programme ou à un script. L'un des plus courants est pour un utilisateur de taperCONTROL-C ou la INTERRUPT key pendant l'exécution d'un script.

Lorsque vous appuyez sur le Ctrl+C clé, une SIGINT est envoyé au script et, conformément à la définition par défaut, le script d'action se termine.

L'autre méthode courante pour délivrer des signaux consiste à utiliser le kill command, dont la syntaxe est la suivante -

$ kill -signal pid

Ici signal est le numéro ou le nom du signal à délivrer et pidest l'ID de processus auquel le signal doit être envoyé. Par exemple -

$ kill -1 1001

La commande ci-dessus envoie le signal HUP ou de raccrochage au programme qui s'exécute avec process ID 1001. Pour envoyer un signal d'arrêt au même processus, utilisez la commande suivante -

$ kill -9 1001

Cela tue le processus en cours avec process ID 1001.

Signaux de piégeage

Lorsque vous appuyez sur la touche Ctrl + C ou Pause de votre terminal pendant l'exécution d'un programme shell, normalement ce programme est immédiatement arrêté et votre invite de commande revient. Cela n'est pas toujours souhaitable. Par exemple, vous pouvez finir par laisser un tas de fichiers temporaires qui ne seront pas nettoyés.

Le piégeage de ces signaux est assez simple et la commande trap a la syntaxe suivante -

$ trap commands signals

Ici, la commande peut être n'importe quelle commande Unix valide, ou même une fonction définie par l'utilisateur, et le signal peut être une liste de n'importe quel nombre de signaux que vous souhaitez intercepter.

Il existe deux utilisations courantes du trap dans les scripts shell -

  • Nettoyer les fichiers temporaires
  • Ignorer les signaux

Nettoyage des fichiers temporaires

À titre d'exemple de la commande trap, ce qui suit montre comment vous pouvez supprimer certains fichiers, puis quitter si quelqu'un essaie d'annuler le programme à partir du terminal -

$ trap "rm -f $WORKDIR/work1$$ $WORKDIR/dataout$$; exit" 2

A partir du moment où ce trap est exécuté dans le programme shell, les deux fichiers work1$$ et dataout$$ sera automatiquement supprimé si le signal numéro 2 est reçu par le programme.

Par conséquent, si l'utilisateur interrompt l'exécution du programme après l'exécution de cette interruption, vous pouvez être assuré que ces deux fichiers seront nettoyés. leexit commande qui suit la rm est nécessaire car sans elle, l'exécution se poursuivrait dans le programme au point où elle s'était arrêtée lors de la réception du signal.

Le signal numéro 1 est généré pour hangup. Soit quelqu'un raccroche intentionnellement la ligne, soit la ligne est accidentellement déconnectée.

Vous pouvez modifier le trap précédent pour supprimer également les deux fichiers spécifiés dans ce cas en ajoutant le signal numéro 1 à la liste des signaux -

$ trap "rm $WORKDIR/work1$$ $WORKDIR/dataout$$; exit" 1 2

Maintenant, ces fichiers seront supprimés si la ligne est suspendue ou si la touche Ctrl + C est enfoncée.

Les commandes spécifiées pour intercepter doivent être placées entre guillemets, si elles contiennent plusieurs commandes. Notez également que le shell scanne la ligne de commande au moment où la commande trap est exécutée et également lorsque l'un des signaux répertoriés est reçu.

Ainsi, dans l'exemple précédent, la valeur de WORKDIR et $$sera remplacé au moment de l'exécution de la commande trap. Si vous souhaitez que cette substitution se produise au moment de la réception du signal 1 ou 2, vous pouvez mettre les commandes entre guillemets simples -

$ trap 'rm $WORKDIR/work1$$ $WORKDIR/dataout$$; exit' 1 2

Ignorer les signaux

Si la commande répertoriée pour trap est nulle, le signal spécifié sera ignoré lors de sa réception. Par exemple, la commande -

$ trap '' 2

Cela spécifie que le signal d'interruption doit être ignoré. Vous voudrez peut-être ignorer certains signaux lors de l'exécution d'une opération que vous ne souhaitez pas interrompre. Vous pouvez spécifier plusieurs signaux à ignorer comme suit -

$ trap '' 1 2 3 15

Notez que le premier argument doit être spécifié pour qu'un signal soit ignoré et n'équivaut pas à écrire ce qui suit, qui a sa propre signification -

$ trap  2

Si vous ignorez un signal, tous les sous-shell ignorent également ce signal. Cependant, si vous spécifiez une action à entreprendre à la réception d'un signal, tous les sous-coquilles prendront toujours l'action par défaut à la réception de ce signal.

Réinitialisation des pièges

Après avoir modifié l'action par défaut à entreprendre à la réception d'un signal, vous pouvez la modifier à nouveau avec le trap si vous omettez simplement le premier argument; alors -

$ trap 1 2

Cela réinitialise l'action à entreprendre à la réception des signaux 1 ou 2 à la valeur par défaut.