Dans quels cas SIGHUP n'est-il pas envoyé à un travail lorsque vous vous déconnectez?

10

J'ai lu une réponse d'un utilisateur qui prétendait que courir

foo 2>&1 >& output.log &

entraînerait la foopoursuite de l'exécution même lorsqu'ils se déconnectent. Selon cet utilisateur, cela a même fonctionné sur des connexions SSH.

Je ne croyais pas vraiment que, car j'avais l'impression qu'en cas de déconnexion de SSH ou de résiliation du TTY, le shell et donc ses processus recevraient un SIGHUP, ce qui les obligerait à se terminer. À mon avis, c'était la seule raison d'utiliser nohupdans de tels cas, ou tmux, screenet al.

J'ai ensuite regardé dans le manuel de glibc :

Ce signal est également utilisé pour signaler la fin du processus de contrôle sur un terminal aux travaux associés à cette session; cette terminaison déconnecte efficacement tous les processus de la session du terminal de contrôle.

Cela semble confirmer mes pensées. Mais en regardant plus loin, il dit :

Si le processus est un leader de session qui a un terminal de contrôle, un signal SIGHUP est envoyé à chaque processus dans la tâche de premier plan, et le terminal de contrôle est dissocié de cette session.

Cela signifie-t-il donc que les emplois mis en arrière-plan ne recevront pas SIGHUP?

À ma plus grande confusion, j'ai exécuté une session Zsh interactive, exécuté yes >& /dev/null &et tapé exit, lorsque Zsh m'a averti que j'avais des travaux en cours et, après avoir tapé exitune deuxième fois, m'a dit qu'il avait SIGHUPed un travail. Faire exactement la même chose dans Bash laisse le travail en cours…

slhck
la source
J'ai eu des problèmes avec un serveur dans le passé qui est soudainement déconnecté via ssh, et mon processus a continué à fonctionner mais sans aucun tty associé, j'ai donc dû me reconnecter et envoyer SIGHUP / TERM / KILL pour y mettre fin. Donc, suivant la même logique, j'ai testé tout à l'heure, tapé logoutet yesfonctionne toujours.
Braiam
En plus de l'envoi ou non de SIGHUP, le fait qu'un processus ait défini un gestionnaire de signal (et intercepte SIGHUP) ou un masque de signal sont des facteurs supplémentaires pour savoir s'il est terminé lors de l'envoi de ce signal. Donc, ce n'est pas parce qu'il continue de fonctionner après la déconnexion qu'il n'a pas été envoyé ce signal
Tim B
Faites-vous référence à cette question: serverfault.com/questions/115999/… ? La réponse semble s'y trouver - c'est RedHat qui ne définit pas shopt par défaut. C'est la particularité de la configuration de RedHat.
Boris Burkov
@Bob Non, je n'ai jamais vu celui-ci auparavant, mais c'est une bonne ressource. Merci!
slhck
Heureux que cela ait aidé. En fait, Raphael fait également référence à cette question.
Boris Burkov

Réponses:

18

Bash semble envoyer le SIGHUPseul s'il a reçu lui-même un SIGHUP, ce qui se produit par exemple lorsqu'un terminal virtuel est fermé ou lorsque la connexion SSH est interrompue. De la documentation :

Le shell se ferme par défaut à réception d'un SIGHUP. Avant de quitter, un shell interactif renvoie le SIGHUP à toutes les tâches, en cours d'exécution ou arrêtées. 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 travaux avec le programme intégré désavoué (voir les commandes de contrôle des travaux) ou marqué pour ne pas recevoir SIGHUP en utilisant disown -h.

Donc, si vous tapez exitou appuyez sur Ctrl+, Dtout le processus d'arrière-plan restera, car cela n'envoie pas de signal de raccrochage au Bash.

Vous pouvez forcer Bash à vous avertir du fait qu'il existe toujours des processus en arrière-plan avec

shopt -s checkjobs

Il existe une option pour envoyer la SIGHUPsortie à la sortie si vous êtes dans un shell interactif ( voir ici ). Mais cela ne fonctionne pas sur ma machine avec Bash 4.2.25. Peut-être que cela fonctionne pour vous

shopt -s huponexit
Raphael Ahrens
la source
Ainsi, lorsqu'une connexion SSH s'interrompt, SIGHUPest envoyée, sinon, avec une sortie propre, les travaux continuent de s'exécuter? Cela explique ce que j'ai vu.
slhck
Oui. Le signal de raccrochage n'est là que pour le cas particulier, lorsque la connexion avec l'utilisateur est interrompue.
Raphael Ahrens
Continuons cette discussion dans le chat .
Martin Kunev
@npostavs merci pour les informations que j'ai ajoutées dans la réponse.
Raphael Ahrens