Différence entre nohup, disown et &

578

Quelles sont les différences entre

$ nohup foo

et

$ foo &

et

$ foo & 
$ disown
lesmana
la source
50
Attendez, vous pouvez désavouer sans spécifier un PID? Génial!
ripper234
34
Il y a aussi foo &!ce qui devrait être égal à le renier dès le début.
user4514
26
Bash ne supporte pas & !.
Jonas Kongslund
20
foo & disowndésavouer immédiatement.
ctrl-alt-delor
9
J'aimerais voir une mention de setsid, et comment cela se rapporte à disownetnohup
YoungFrog

Réponses:

557

Voyons d'abord ce qui se passe si un programme est lancé à partir d'un shell interactif (connecté à un terminal) sans &(et sans aucune redirection). Supposons donc que vous venez de taper foo:

  • Le processus en cours fooest créé.
  • Le processus hérite des commandes stdin, stdout et stderr du shell. Par conséquent, il est également connecté au même terminal.
  • Si le shell reçoit un SIGHUP, il envoie également un message SIGHUPau processus (ce qui entraîne normalement la fin du processus).
  • Sinon, le shell attend (est bloqué) jusqu'à la fin du processus.

Maintenant, regardons ce qui se passe si vous mettez le processus en arrière-plan, c'est à dire, tapez foo &:

  • Le processus en cours fooest créé.
  • Le processus hérite de stdout / stderr du shell (il écrit donc toujours sur le terminal).
  • Le processus en principe hérite également de stdin, mais dès qu'il tente de lire stdin, il est arrêté.
  • Il est placé dans la liste des tâches d’arrière-plan gérées par le shell, ce qui signifie notamment:
    • Il est répertorié avec jobset est accessible à l'aide de %n(où nest le numéro de travail).
    • Il peut être transformé en tâche de premier plan en utilisant fg, auquel cas il continue comme si vous ne l' utilisiez pas &(et s'il a été arrêté en raison d'une tentative de lecture depuis une entrée standard, il peut maintenant passer à la lecture depuis le terminal).
    • Si le shell reçoit un SIGHUP, il envoie également un message SIGHUPau processus. En fonction du shell et éventuellement des options définies pour le shell, lorsqu’il se termine, il envoie également un message SIGHUPau processus.

disownSupprime maintenant le travail de la liste des travaux du shell, afin que tous les sous-points ci-dessus ne s'appliquent plus (y compris le processus envoyé SIGHUPpar le shell). Cependant, notez qu'il est toujours connecté au terminal, donc si le terminal est détruit (ce qui peut se produire s'il s'agissait d'un pty, comme ceux créés par xtermou ssh, et si le programme de contrôle est arrêté, en fermant xterm ou en mettant fin à la connexion SSH ) , le programme échouera dès qu’il essaiera de lire à partir d’une entrée standard ou d’écrire sur une sortie standard.

En nohuprevanche, il convient de séparer efficacement le processus du terminal:

  • Il ferme l'entrée standard (le programme ne pourra lire aucune entrée, même si celle-ci est exécutée au premier plan. Elle n'est pas arrêtée, mais recevra un code d'erreur ou EOF).
  • Il redirige la sortie standard et l'erreur standard vers le fichier nohup.outafin que le programme n'échoue pas pour l'écriture sur la sortie standard en cas d'échec du terminal. Ainsi, le processus écrit n'est pas perdu.
  • Cela empêche le processus de recevoir un SIGHUP(donc le nom).

Notez que nohupcela ne supprime pas le processus du contrôle du travail du shell et ne le met pas non plus en arrière-plan (mais comme un nohuptravail en avant-plan est plus ou moins inutile, vous le mettriez généralement en arrière-plan &). Par exemple, contrairement à with disown, le shell vous indiquera quand même le travail nohup (sauf si le shell est terminé avant, bien sûr).

Donc, pour résumer:

  • & met le travail en arrière-plan, c’est-à-dire qu’il bloque les tentatives de lecture des entrées et empêche le shell d’attendre son achèvement.
  • disownsupprime le processus du contrôle de travail du shell, mais le laisse toujours connecté au terminal. L’un des résultats est que le shell ne l’enverra pas SIGHUP. De toute évidence, il ne peut être appliqué qu'aux tâches en arrière-plan, car vous ne pouvez pas y entrer lorsqu'un travail de premier plan est en cours d'exécution.
  • nohupdéconnecte le processus du terminal, redirige sa sortie vers nohup.outet le protège SIGHUP. L'un des effets (celui de la dénomination) est que le processus ne recevra aucun message envoyé SIGHUP. Il est complètement indépendant du contrôle des travaux et pourrait en principe être utilisé également pour les travaux au premier plan (bien que cela ne soit pas très utile).
celtschk
la source
8
+1 merci. Que se passe-t-il quand on utilise désown, nohup et & together alors?
Tim
15
Si vous utilisez les trois ensemble, le processus s'exécute en arrière-plan, est supprimé du contrôle des tâches du shell et est effectivement déconnecté du terminal.
celtschk le
1
et quelle est la différence entre disown %1et disown -h %1? Le second restera comme un travail normal (mais ignore le signal HUP) jusqu'à la sortie du terminal?
Schemacs
4
Peut - être vaut y compris (foo&)sous - shell
jiggunjer
169

L'utilisation &du programme s'exécute en arrière-plan. Vous obtiendrez une nouvelle invite du shell au lieu de bloquer jusqu'à la fin du programme. nohupet disownsont en grande partie indépendants; ils suppriment les signaux SIGHUP (raccrochage) afin que le programme ne soit pas automatiquement tué lorsque le terminal de contrôle est fermé. nohupfait cela quand le travail commence. Si vous ne faites pas nohupun travail quand il commence, vous pouvez utiliser disownpour modifier un travail en cours d'exécution; sans aucun argument, il modifie le travail en cours, qui est celui qui vient d'être mis en arrière-plan

Michael Mrozek
la source
10
Différence mineure entre nohup et disown: la commande disown le supprimera de votre liste de tâches; nohup ne le fera pas.
Shawn J. Goff Le
191
nohupet disownon peut dire que les deux suppriment SIGHUP, mais de différentes manières. nohupfait que le programme ignore initialement le signal (le programme peut le changer). nohupessaie également de faire en sorte que le programme ne dispose pas d'un terminal de contrôle, de sorte qu'il ne soit pas envoyé SIGHUPpar le noyau lorsque le terminal est fermé. disownest purement interne à la coquille; le shell n’envoie pas à la SIGHUPfin.
Gilles
27
@ Gilles, votre commentaire mérite une réponse en soi.
Lesmana
5
Juste une clarification sur le commentaire de @ ShawnJ.Goff concernant le disownretrait du travail de la liste des travaux. Si vous ne spécifiez pas d'option, elle est supprimée de la liste des tâches. Cependant , si vous spécifiez l' -hoption, chaque spécification de travail n'est pas supprimée de la table. Au lieu de cela, cela signifie que le fichier SIGHUPn’est pas envoyé au travail si le shell reçoit un SIGHUP.
Tacotuesday
4
Juste pour clarifier, l'utilisation &ne vous donne pas un terminal, il se détache stdindu processus et le fait fonctionner en arrière-plan, mais les deux stdoutet stderrsont toujours attachés au tty actuel. Cela signifie que vous pouvez mélanger le texte de différents programmes, ce qui peut être assez gênant si vous le faites gimp &et obtenez beaucoup d'erreurs GTK + tout en essayant d'utiliser ce tty pour autre chose.
Frank
8

Voici mon expérience d’essayer d’exécuter soffice en arrière-plan, à la suite d’une commande qui ne se termine pas (par exemple tail). Pour cet exemple, je vais utiliser sleep 100.

Et

#!/bin/bash
/opt/libreoffice4.4/program/soffice -invisible -nofirststartwizard &
sleep 100

Je vois les journaux de soffice / en appuyant sur Ctrl- Csoffice s’arrête

nohup .. &

#!/bin/bash
nohup /opt/libreoffice4.4/program/soffice -invisible -nofirststartwizard &
sleep 100

Je ne vois pas les journaux de soffice / en appuyant sur Ctrl- Csoffice s'arrête

et désavoué

#!/bin/bash
/opt/libreoffice4.4/program/soffice -invisible -nofirststartwizard & disown
sleep 100

Je vois les journaux de soffice / en appuyant sur Ctrl- Csoffice s’arrête

setsid .. &

#!/bin/bash
setsid /opt/libreoffice4.4/program/soffice -invisible -nofirststartwizard &
sleep 100

Je vois les journaux du bureau / en appuyant sur Ctrl- le Cbureau ne s’arrête pas

Pour économiser de l'espace::
nohup setsid ..ne montre pas les journaux / soffice N'ARRÊTE PAS le Ctrl-C
nohup avec & disownà la fin: ne montre pas les journaux / le soffice s'arrête sur Ctrl-C

Marinos An
la source
2
Bien que j'apprécie l'effort de mentionner setsid et de montrer ce qui se passe dans cette situation spécifique, j'aimerais une réponse plus complète. En particulier, la différence et les similitudes de chaque solution, à la fois visibles (que se passe-t-il lorsque le shell ou le terminal est fermé, où va la sortie, ...) et invisibles (comment les choses se passent sous le capot et leurs implications). La réponse acceptée est une bonne base pour cela.
YoungFrog
1
@YoungFrog je suis d'accord sur ce!
Marinos Un
Pour moi, nohup ⟨command⟩ & disownle processus créé ne s’arrête pas Ctrl+C.
k.stm
@ k.stm Avez-vous essayé soffice? sofficela commande semble avoir quelque chose de différent. J'ai donc envisagé de l'ajouter ici à titre d'exception à la règle. par exemple, lors de l'utilisation de :, le fait d' nohup .. &appuyer Ctrl-cnormalement ne provoque pas l'arrêt de la commande, mais avec sofficeelle. J'attends que quelqu'un marche dessus et explique pourquoi cela se produit avec soffice :)
Marinos Un
@MarinosAn Oui, je l'ai fait. J'ai couru nohup soffice &et pressé Ctrl+C. Rien ne s'est passé, comme prévu.
k.stm