Pourquoi le processus d'arrière-plan nohup est-il tué?

10

J'ai essayé de démarrer un script shell via une session distante, qui démarre un processus en arrière-plan à l'aide de la commande.

nohup python3 run.py > nohup.out &

Lorsque la session distante est fermée, le processus est interrompu avec le message:

Signal capté SIGHUP

SIGHUP capturé mais non démonisé. Quitter.

Je ne comprends pas; pourquoi le processus est-il tué lorsqu'il a été démarré en arrière-plan à l'aide de nohup & ?

Mani le plus recherché
la source
1
J'étais confus par tout le comportement inattendu du contrôle des tâches shell. Maintenant, j'utilise tmuxet ignore nohupcomplètement ou renie ou tâche d'arrière-plan complètement.
Siyuan Ren

Réponses:

10

Votre programme Python se défait nohup.

nohupignore le signal de raccrochage avec SIG_IGNpuis charge en chaîne votre programme dans le même processus.

Votre programme Python réinitialise rapidement la gestion du signal pour le signal de raccrochage, en installant son propre gestionnaire de signal. Ce gestionnaire vérifie une fonction interne (qui n'est pas très bien conçue, étant basée sur des hypothèses erronées, si c'est celle que j'ai vue) et décide que la ligne de conduite appropriée à la réception d'un signal de raccrochage consiste à imprimer ce message et sortir.

Votre programme Python par conception n'est pas nohup-able. Sur un système avec un shell de contrôle des travaux et une sémantique de session / travail POSIX, vous devez être disownle travail afin que le shell ne le sache jamais pour lui envoyer un signal de raccrochage en premier lieu.

(Même cela ne suffit pas sur les systèmes d'exploitation systemd. Parce que les personnes systemd ont fait une petite oreille de porc de leur mécanisme de session de connexion à l'espace utilisateur, vous devez également vous assurer que le mécanisme de systemd qui signale l'arrêt du système, plutôt que de raccrocher, pour les sessions de connexion à chaque déconnexion ne se déclenchent pas non plus.)

Lectures complémentaires

JdeBP
la source
3
Est-ce leur programme Python qui le fait, ou est-ce l'interpréteur Python (/ environnement d'exécution) qui le fait silencieusement derrière leur dos?
ilkkachu
De plus, sous Mac OS, la déconnexion d'une session ssh vous tue les travaux de shell, même lorsque vous commencez à utiliser nohup; n'ont pas trouvé de remède
imhotap
Eh bien, si le problème est le gestionnaire de signal, l'OP pourrait simplement changer le gestionnaire de signal en un gestionnaire qui ne tue pas le processus. Cela devrait fonctionner indépendamment de qui installe un tel gestionnaire de signal. Je voudrais ajouter concernant ssh: parfois, même si le processus est maintenu en vie, il peut avoir des problèmes. Il y a quelques années, j'ai perdu un peu de temps à essayer de comprendre certaines erreurs de permission et, à la fin, le coupable était Kerberos: lorsque la session ssh a été fermée, les jetons ont expiré, j'ai donc dû créer de nouveaux jetons à utiliser à la place de ceux de la session ssh.
Bakuriu
@JdeBP J'ai essayé setsid nohup python3 run.py > nohup.out &, setsid a résolu ce problème. Est-ce une bonne approche?
Mostwanted Mani