Pourquoi bash ignore SIGTERM?

Parfois, quand je veux me déconnecter rapidement, je kill -15 -1 . J'ai remarqué que bash ignore SIGTERM.

Je me request quelle est la raison d'un tel comportement bash ?

Ce n'est pas très UNIX'y d'ignorer SIGTERM sans une bonne raison, n'est-ce pas?

METTRE À JOUR:

même (non) effet pour tous:

 $ kill -TERM $$ $ type kill kill is a shell builtin $ command kill -TERM $$ $ /bin/kill -TERM $$ 

UPDATE2:

De l' homme bash :

Quand bash est interactif, en l'absence de pièges, il ignore SIGTERM

Donc, c'est fait express. Mais pourquoi?

Premièrement, ce n'est pas spécifique à bash. ATT ksh, dash et zsh se comportent de la même façon: ils ignorent SIGTERM et SIGQUIT pendant l'édition de la command line; comme pour mksh, il ne quitte pas mais les traite comme SIGINT.

Le manuel ksh et le manuel bash justifient que l'on ignore SIGTERM en ces termes:

de sorte que kill 0 ne tue pas une coquille interactive

kill 0 tue tous les process du groupe de process dans lesquels se trouve le shell¹. En résumé, le groupe de process est constitué de tous les process exécutés au premier plan sur un terminal, ou de tous les process d'un travail en arrière-plan ou suspendu.

Plus précisément, c'est ce qui se passe dans les coquilles modernes avec le contrôle du travail . Dans de tels obus, kill 0 ne serait pas utile, car la coquille serait dans un groupe de process qui lui est propre. Les shells plus anciens (ou shells modernes après set +m ) n'ont pas créé de groupes de process pour les commands d'arrière-plan. Vous pouvez donc utiliser la command kill 0 pour tuer toutes les commands d'arrière-plan sans vous déconnecter. Ainsi, la logique de kill 0 ressemble à une ancienne qui n'est plus justifiée de nos jours mais conservée pour une rétrocompatibilité.

Cependant, il existe d'autres situations similaires où rendre la coquille immunitaire est utile. Considérez le cas où vous avez des process qui épousent un terminal et que vous voulez les tuer sans vous déconnecter. De nombreux systèmes ont un outil comme pkill qui vous permet de tuer les process s'exécutant sur un terminal. Vous pouvez exécuter pkill -t $TTY ou pkill -QUIT -t $TTY pour tuer tous les process en cours d'exécution sur le terminal en cours, à l'exception du shell qui ignore le signal.

Un shell disparaît normalement lorsque l'user le quitte (avec une command comme exit ou logout ), ou lorsque son terminal signale la fin de l'input (l'user peut le faire en appuyant sur Ctrl + D ) ou disparaît complètement. Dans ce dernier cas, le shell reçoit le signal SIGHUP, et il n'ignore pas celui-là.

Dans le cas où vous vous déconnectez d'une session X, kill -15 -1 fera, car il tue l'émulateur de terminal qui amène le shell à recevoir SIGHUP. En fait, il suffit de tuer le server X, mais cela nécessite de find son ID de process. Si vous voulez que la même command fonctionne sur une session de text, vous pouvez utiliser kill -15 -1; exit kill -15 -1; exit . C'est tout à fait une command dangereuse d'avoir à scope de main de toute façon.

¹ Cela ne semble pas être mentionné dans les manuels de shell en règle générale; c'est une caractéristique de l'appel système sous-jacent. Il est mentionné explicitement dans la spécification POSIX .
² Pour ce faire, exécutez les jobs -l pour voir la list des tâches avec leur ID de groupe de process, puis kill -123 -456 … pour tuer les groupes de process.

Cela pourrait répondre à votre question:

Lorsque Bash est interactif, en l'absence de pièges, il ignore SIGTERM (de sorte que 'kill 0' ne tue pas un shell interactif), et SIGINT est intercepté et manipulé (de sorte que le builtin d'attente est interruptible). Lorsque Bash reçoit un SIGINT, il éclate toutes les loops en cours d'exécution. Dans tous les cas, Bash ignore SIGQUIT. Si le contrôle des travaux est activé (voir Contrôle des tâches), Bash ignore SIGTTIN, SIGTTOU et SIGTSTP.

Les commands non-embeddedes démarrées par Bash ont des gestionnaires de signaux définis sur les valeurs héritées par le shell de son parent. Lorsque le contrôle des travaux n'est pas activé, les commands asynchronouss ignorent SIGINT et SIGQUIT en plus de ces gestionnaires hérités. Les commands exécutées à la suite de la substitution de command ignorent les signaux de command de travail générés par le keyboard SIGTTIN, SIGTTOU et SIGTSTP.

Le shell quitte par défaut à la réception d'un SIGHUP. Avant de quitter, un shell interactif renvoie le SIGHUP à tous les jobs, en cours ou arrêtés. Les travaux arrêtés sont envoyés à SIGCONT pour s'assurer qu'ils reçoivent le SIGHUP. Pour empêcher le shell d'envoyer le signal SIGHUP à un travail particulier, il doit être supprimé de la table des jobs avec le renfoncement embedded (voir Job Control Builtins) ou marqué pour ne pas recevoir SIGHUP en utilisant le désavantage -h.

Si l'option shell huponexit a été définie avec shopt (voir The Shopt Builtin), Bash envoie un SIGHUP à tous les jobs lorsqu'un shell de connection interactif se ferme.

Si Bash attend qu'une command se termine et reçoive un signal pour lequel un trap a été défini, le trap ne sera pas exécuté tant que la command ne sera pas terminée. Lorsque Bash attend une command asynchronous via la fonction wait, la réception d'un signal pour lequel un trap a été activé fera immédiatement revenir l'exit builtin avec un état de sortie supérieur à 128, immédiatement après lequel le trap est exécuté.

SOURCE : Le manuel GNU Bash