Si je lance un processus d'arrière-plan puis me déconnecte, continuera-t-il de s'exécuter?

29

Poser cette question après une longue discussion avec un collègue, je voudrais vraiment une clarification ici.

Je lance un processus d'arrière-plan, soit en ajoutant " &" à la ligne de commande, soit en l'arrêtant CTRL-Zet en le reprenant en arrière-plan avec " bg". Ensuite, je me déconnecte.

Ce qui se produit?

Nous étions sûrs qu'il aurait dû être tué par un SIGHUP, mais cela ne s'est pas produit; lors de la reconnexion, le processus était en cours d'exécution et a pstreemontré qu'il était "adopté" par init.

Est-ce le comportement attendu?

Mais alors, si c'est le cas, quel est le nohupbut de la commande? Il semble que le processus ne sera pas tué de toute façon, avec ou sans lui ...


Modifier 1

Quelques détails supplémentaires:

  • La commande a été lancée à partir d'une session SSH, pas à partir de la console physique.
  • La commande a été lancée sans nohup et / ou &; il a ensuite été suspendu avec CTRL-Zet repris en arrière-plan avec bg.
  • La session ssh n'a pas chuté. Il y a eu une déconnexion réelle ( exitcommande " ").
  • Le processus était une scpopération de copie de fichiers.
  • Lorsque vous vous reconnectez, pstreele processus est en cours d'exécution et est enfant de init.

Modifier 2

Pour énoncer plus clairement la question: mettre un processus en arrière-plan (en utilisant &ou bg) le fera-t-il ignorer SIGHUP, tout comme la nohupcommande?


Modifier 3

J'ai essayé d'envoyer manuellement un SIGHUPà scp: il s'est arrêté, donc il n'ignore certainement pas le signal.

Ensuite, j'ai essayé de nouveau de le lancer, de le mettre en arrière-plan et de me déconnecter: il a été "adopté" par initet a continué à fonctionner, et je l'ai trouvé là lors de la reconnexion.

Je suis assez perplexe maintenant. On dirait que non a SIGHUPété envoyé du tout jusqu'à la fermeture de session.

Massimo
la source
Je n'ai vu aucune mention d'E / S de console là-dedans, ce qui déclenchera également les choses. Avez-vous détourné des choses, par exemple 1>/dev/null 2>&1pour bash, etc.?
Avery Payne, le
Non, je ne l'ai pas fait. SCP bien sûr ne nécessitait pas d'entrée standard ... et la sortie standard ne semblait pas être un problème.
Massimo
Que votre shell soit exécuté ou non en tant que shell de connexion modifie les performances, ce qui peut être le cas ici.
Warner
Fait d'autres tests; Je l'ai résumé ici: serverfault.com/questions/117152 .
Massimo

Réponses:

20

Réponse trouvée.

Pour BASH, cela dépend de l' huponexitoption shell, qui peut être affichée et / ou définie à l'aide de la shoptcommande intégrée .

Il semble que cette option soit désactivée par défaut, au moins sur les systèmes basés sur RedHat.

Plus d'informations sur la page de manuel BASH :

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 à une tâche particulière, il doit être supprimé de la table des tâches avec la commande intégrée désavoué (voir COMMANDES DE CONSTRUCTION D'INTERPRÉTEUR ci-dessous) ou marqué pour ne pas recevoir SIGHUP à l'aide de la commande disown -h.

Si l'option shell huponexit a été définie avec shopt, bash envoie un SIGHUP à toutes les tâches lorsqu'un shell de connexion interactif se ferme.

Massimo
la source
2
C'est un défaut stupide, mais mes tripes me disent que c'est une faute RH plutôt que bash. Btw, avec zsh vous pouvez utiliser &! comme raccourci pour renier, et les processus fourchus avec & obtiennent un soupir.
Jürgen Strobel
7

Je suis d'accord avec Warner et je veux juste ajouter que vous pouvez empêcher le shell d'envoyer SIGHUP avec la commande "disown" intégrée. La page de manuel bash contient une bonne description.

Kim
la source
4

Vous pouvez utiliser la commande nohup pour lancer la commande et rediriger la sortie dans un fichier de sortie nohup. Depuis la page de manuel de nohup:

nohup - run a command immune to hangups, with output to a non-tty

L'autre option consiste à utiliser la commande d' écran . L'avantage de l'utilisation de l'écran est que vous pouvez vous reconnecter au processus ultérieurement.

Jim
la source
Pourquoi les downvotes? Utiliser nohup et screen sont des moyens parfaitement acceptables pour éviter de tuer un processus lors de la déconnexion. Il y en a d'autres, mais les deux fonctionnent. Quel est le problème?
Jim
2
Je pense que c'est un bon point, mais le Q explique pourquoi ses processus ne sont pas tués PAS "comment les empêcher de se faire tuer".
CarpeNoctem
2

Lorsque vous forkez un processus en arrière-plan, il s'agit toujours du processus enfant du shell qui l'exécute.

Tous les processus enfants exécutés sous un shell reçoivent un SIGHUP à la sortie. Les performances varient légèrement en fonction de la situation exacte, qui est détaillée dans la page de manuel de bash. D'autres obus ont probablement des descriptions similaires.

Apache et d'autres démons rechargent généralement la configuration sur SIGHUP. Les utilitaires de l'espace utilisateur meurent souvent. Les performances de l'application liées aux signaux peuvent être uniques à l'application.

Warner
la source
Donc, le processus aurait juste dû recevoir un SIGHUP dans ce cas, non? Peut-être qu'il l'a juste ignoré, je vais vérifier.
Massimo
Oui, exactement. C'est ce que je pense être la situation. Si vous doutez vraiment des performances documentées, vous pouvez pirater un petit script pour piéger le signal et l'enregistrer.
Warner
0

Quel a été le processus? Les performances décrites dans la publication précédente 1 étaient exactes.

Certaines fonctions et processus de script peuvent intercepter des signaux. tandis que les boucles peuvent s'enfuir comme des fous.

Voir:

Abandon de session SSH - La commande continue-t-elle de s'exécuter?

Modifier 1 à 16h22

Depuis la page de manuel bash:

The shell exits by default upon receipt of a SIGHUP.   Before  exiting,
an  interactive  shell  resends  the  SIGHUP  to  all  jobs, running or
topped.

La recherche initiale 1 montre qu'OpenSSH ignore probablement SIGHUP, peut-être plus de signaux.

Warner
la source
Ce poste m'a en fait poussé à poser la question. Pour plus de détails, voir modifier ci-dessus.
Massimo
2
Les réponses dans l'autre thread donnent l'impression que vous devez lire la commande SCP que vous utilisez et voir comment elle répond à SIGHUP
mfinni
Et «nohup» est pour les commandes qui, vous le savez, mourront avec un SIGHUP et vous ne le voulez pas, je suppose.
mfinni
La page de manuel ne le dit tout simplement pas; Je vais essayer de le tuer -HUP demain ...
Massimo
-1

Si vous n'avez pas lancé la commande via un outil comme screen, alors à la fin de la session, faites tous les travaux / tâches associés à cette session.

garenne
la source
C'est exactement ce que je pensais, sauf que ... ce n'est tout simplement pas le cas.
Massimo
ils ont chaque fois que j'ai fait ce que vous avez décrit ... cela dépend peut-être du shell que vous utilisez?
warren
-1 Ils ne le font pas; la réponse n'est pas si simple. Je viens de tester un simple script shell que j'ai commencé en arrière-plan; il a bouclé et envoyé la sortie vers un fichier temporaire. Il a continué à fonctionner après avoir quitté le terminal (comme le montre tail -fle fichier temporaire. Ceci sur une machine CentOS 7.1 utilisant bash.
Mike S
@MikeS - veuillez démontrer. Je n'ai jamais été témoin du comportement que vous décrivez
warren
@warren - Voir ma réponse à serverfault.com/questions/117152/… . Notez qu'un certain nombre de personnes déclarent un comportement différent de ce que vous décrivez; en effet, Massimo a posté précisément parce que son processus s'est poursuivi.
Mike S