Un processus n'est pas "tué avec SIGHUP" - du moins, pas au sens strict du terme. Au lieu de cela, lorsque la connexion est interrompue, le processus de contrôle du terminal (dans ce cas, Bash) reçoit un signal de raccrochage*, généralement abrégé en "signal HUP", ou simplement SIGHUP.
Désormais, lorsqu'un processus reçoit un signal, il peut le gérer comme il le souhaite**. La valeur par défaut pour la plupart des signaux (y compris HUP) est de quitter immédiatement. Cependant, le programme est libre d'ignorer le signal à la place, ou même d'exécuter une sorte de fonction de gestion de signal.
Bash choisit la dernière option. Son gestionnaire de signal HUP vérifie si l'option "huponexit" est vraie, et si c'est le cas, envoie SIGHUP à chacun de ses processus enfants. Ce n'est qu'une fois que c'est fini avec cela que Bash se ferme.
De même, chaque processus enfant est libre de faire ce qu'il veut lorsqu'il reçoit le signal :laissez-le sur la valeur par défaut (c'est-à-dire qu'il meurt immédiatement), ignorez-le ou exécutez un gestionnaire de signal.
Nohup change uniquement l'action par défaut du processus enfant en "ignorer". Cependant, une fois que le processus enfant est en cours d'exécution, il est libre de modifier sa propre réponse au signal.
C'est, je pense, pourquoi certains programmes meurent même si vous les avez exécutés avec nohup :
- Nohup définit l'action par défaut sur "ignorer".
- Le programme doit effectuer une sorte de nettoyage lorsqu'il se termine, il installe donc un gestionnaire SIGHUP, écrasant accessoirement le drapeau "ignorer".
- Lorsque le SIGHUP arrive, le gestionnaire s'exécute, nettoie les fichiers de données du programme (ou tout ce qui doit être fait) et quitte le programme.
- L'utilisateur ne connaît pas ou ne se soucie pas du gestionnaire ou du nettoyage, et voit simplement que le programme s'est arrêté malgré nohup.
C'est là qu'intervient le "désaveu". Un processus désavoué par Bash ne reçoit jamais le signal HUP, quelle que soit l'option huponexit. Ainsi, même si le programme configure son propre gestionnaire de signal, le signal n'est jamais réellement envoyé, de sorte que le gestionnaire ne s'exécute jamais. Notez cependant que si le programme essaie d'afficher du texte à un utilisateur déconnecté, cela provoquera une erreur d'E/S, ce qui pourrait entraîner la fermeture du programme de toute façon.
* Et, oui, avant que vous ne posiez la question, la terminologie de "raccrochage" est un vestige de l'époque de l'ordinateur central commuté d'UNIX.
** La plupart des signaux, de toute façon. SIGKILL, par exemple, toujours provoque l'arrêt immédiat du programme, point.
Les points 1 à 4 sont corrects. Je ne sais rien du point 5. Quant à votre dernier point, une belle application, écran , vous permettra de laisser tous les processus s'exécuter jusqu'à leur fin naturelle, quelle que soit la façon dont vous mettez fin à votre connexion. L'écran est dans les dépôts.
La description de l'homme de l'écran n'est pas facile à lire, mais, entre autres, elle indique :
Lorsque screen est appelé, il crée une fenêtre unique contenant un shell (ou la commande spécifiée) puis s'écarte de votre chemin afin que vous puissiez utiliser le programme comme vous le feriez normalement. Ensuite, à tout moment, vous pouvez créer de nouvelles fenêtres (plein écran) avec d'autres programmes (y compris plus de shells), fermer les fenêtres existantes, afficher une liste de fenêtres, activer et désactiver la journalisation des sorties, copier et coller du texte entre fenêtres, afficher l'historique de défilement, basculer entre les fenêtres comme vous le souhaitez, etc. Toutes les fenêtres exécutent leurs programmes de manière totalement indépendante les unes des autres. la session est détachée du terminal de l'utilisateur . Lorsqu'un programme se termine, screen (par défaut) tue la fenêtre qui le contenait. Si cette fenêtre était au premier plan, l'affichage revient à la fenêtre précédente; s'il n'en reste plus, l'écran se ferme.
J'ai mis en évidence la partie la plus importante :vous pouvez détacher la fenêtre avec la commande Ctrl+a+d, puis vous pouvez tuer/déconnecter votre session, et la fenêtre maintenant détachée continuera à vivre, avec les programmes à l'intérieur toujours en cours d'exécution. Lorsque vous vous reconnectez, par exemple en lançant une nouvelle session ssh, la commande screen -r reprendra la session d'écran qui avait été détachée plus tôt, avec toutes les sorties vers l'erreur standard/sortie clairement visibles.