`Disown -h` et` nohup` fonctionnent-ils efficacement de la même manière?

18

disown

  • oblige un shell à ne pas envoyer SIGHUP à son travail renié lorsque le shell se termine, et

  • supprime le travail désavoué du contrôle du travail du shell.

Le premier est-il le résultat du second? En d'autres termes, si un processus démarré à partir d'un shell est supprimé du contrôle de travail du shell de quelque façon que ce soit, le shell n'enverra-t-il pas SIGHUP au processus lorsque le shell se terminera?

disown -h garde toujours un processus sous le contrôle du travail d'un shell. Cela signifie-t-il que disown -hfait qu'un processus reçoit toujours SIGHUP envoyé par le shell, mais configure l'action de SIGHUP par le processus pour qu'il soit "ignoré"? Cela ressemble à nohup.

$ sleep 123 & disown -h
[1] 26103
$ jobs
[1]+  Running                 sleep 123 &
$ fg 1
sleep 123
$ ^Z
[1]+  Stopped                 sleep 125
$ bg 1
[1]+ sleep 123 &
$ exit

$ ps aux | grep sleep
t        26103  0.0  0.0  14584   824 ?        S    15:19   0:00 sleep 123

Faire disown -het nohuptravailler efficacement la même chose, si nous ne tenons pas compte de leur différence dans l'utilisation d'un terminal?

Merci.

Tim
la source
Une autre différence non discutée ici est que si vous n'utilisez pas nohup, vous devez rediriger stdin / stdout / stderr loin du TTY (si votre shell d'origine est connecté à un) vous-même. (OTOH, je considère en fait cette meilleure pratique que de compter sur un défaut codé en dur flagrant comme ./nohup.out).
Charles Duffy

Réponses:

21

nohupet disown -hne sont pas exactement la même chose.

Avec disown, un processus est supprimé de la liste des travaux dans le shell interactif actuel. L'exécution jobsaprès le démarrage d'un processus d'arrière-plan et l'exécution disownn'affichera pas ce processus en tant que travail dans le shell. Un job renié ne recevra pas HUPde shell à sa sortie (mais voir note à la fin).

Avec disown -h, le travail n'est pas supprimé de la liste des travaux, mais le shell ne lui enverrait pas de HUPsignal s'il se fermait (mais voir la note à la fin).

L' nohuputilitaire ignore le HUPsignal et démarre l'utilitaire donné. L'utilitaire hérite du masque de signal nohupet ignorera donc également le HUPsignal. Lorsque le shell se termine, le processus reste un processus enfant de nohup(et nohupest re-parenté init).

La différence est que le processus démarré avec nohupignore HUPquel que soit le destinataire du signal. Les processus désavoué sont tout simplement pas envoyé un HUPsignal de par le shell , mais peuvent encore être envoyés le signal par exemple kill -s HUP <pid>et ne l' ignorer.

Notez que ce HUPn'est envoyé aux travaux d'un shell que si

  • le shell est un shell de connexion et l' huponexitoption shell est définie, ou
  • la coquille elle-même reçoit un HUPsignal.

Bits pertinents du bashmanuel (c'est moi qui souligne):

SIGNAUX

[...]

Le shell se ferme par défaut à réception d'unSIGHUP . Avant de quitter, un shell interactif renvoie le SIGHUPà tous les travaux, en cours d'exécution ou arrêtés. Les travaux arrêtés sont envoyés SIGCONTpour 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 le disownmodule intégré (voir SHELL BUILTIN COMMANDSci - dessous) ou marqué pour ne pas recevoir à l' SIGHUP aide disown -h.

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

disown [-ar] [-h] [jobspec ... | pid ... ]

Sans options, supprimez chacun jobspecde la table des travaux actifs. [...] Si l' -hoption est donnée, chacune jobspecn'est pas supprimée de la table, mais est marquée pour SIGHUPne pas être envoyée au job si le shell reçoit unSIGHUP . [...]

En relation:

Kusalananda
la source
Je reçois bash: disown: nohup: no such jobet même pour sleepet 5depuis disown nohup sleep 5 &. Que vouliez-vous dire par ce deuxième commandement de la dernière phrase?
Ruslan
@Ruslan Oui, il me manque un &(et l'ordre de nohupet disownétait également faux). Merci. Mettra à jour maintenant.
Kusalananda
@Tim Désolé pour la modification excessive de la réponse. Il a fallu un certain temps pour comprendre. J'ai fini maintenant.
Kusalananda
Merci. disownrend un shell non envoyé SIGHUP à un enfant en supprimant l'enfant de la liste des tâches du shell. Comment y disown -hparvenir?
Tim
4

Ils sont différents:

  • disown supprime le travail de la table des travaux actifs. Poursuit ensuite son travail actuel. Avec -h, le processus n'est PAS envoyé SIGHUP. Il est plutôt laissé mourir avec la coquille qui le contient, quand il reçoit un SIGHUP.

  • nohup ignore le HUP. Ensuite, tout ce qui aurait été transmis au terminal par la fermeture du processus va à la place dans un fichiernohup.out .

    nohup est défini par POSIX tandis que le désavertissement ne l'est pas.

Michael Prokopec
la source
Que voulez-vous dire, "mourir avec la coquille qui la contient"? Tuer un processus parental ne tue pas en soi un enfant. Les programmes dont les terminaux sont fermés meurent généralement en raison d'échecs liés aux tentatives d'interaction avec un descripteur de fichier attaché au PTY du terminal, mais si stdin / stdout / stderr sont redirigés ailleurs, cela ne se produira pas.
Charles Duffy