web-dev-qa-db-fra.com

Différence entre Nohup, disown et &

Quelles sont les différences entre

$ Nohup foo

et

$ foo &

et

$ foo & 
$ disown
600
lesmana

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

  • Le processus exécutant foo est créé.
  • Le processus hérite de 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 SIGHUP au processus (ce qui entraîne normalement l'arrêt 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 exécutant foo est créé.
  • Le processus hérite de stdout/stderr du Shell (il écrit donc toujours sur le terminal).
  • Le processus hérite en principe également de stdin, mais dès qu'il essaie de lire à partir de stdin, il est arrêté.
  • Il figure dans la liste des jobs d'arrière-plan gérés par Shell, ce qui signifie notamment:
    • Il est répertorié avec jobs et est accessible à l'aide de %n (où n est le numéro du travail).
    • Il peut être transformé en travail de premier plan à l'aide de fg, auquel cas il continue comme si vous n'auriez pas utilisé & dessus (et s'il a été arrêté en raison d'une tentative de lecture à partir de l'entrée standard, il peut maintenant procéder à la lecture à partir du terminal).
    • Si le shell a reçu un SIGHUP, il envoie également un SIGHUP au processus. Selon le shell et éventuellement les options définies pour le shell, lors de la fermeture du shell, il enverra également un SIGHUP au processus.

Maintenant, disown supprime le travail de la liste des travaux du Shell, de sorte que tous les sous-points ci-dessus ne s'appliquent plus (y compris le processus qui reçoit un SIGHUP par le Shell). Notez cependant qu'il est toujours connecté au terminal, donc si le terminal est détruit (ce qui peut arriver s'il s'agissait d'un pty, comme ceux créés par xterm ou ssh, et le programme de contrôle est terminé, en fermant le xterm ou en mettant fin à la connexion SSH ), le programme échouera dès qu'il essaiera de lire à partir de l'entrée standard ou d'écrire sur la sortie standard.

En revanche, Nohup fait pour séparer efficacement le processus du terminal:

  • Il ferme l'entrée standard (le programme ne pourra pas lire aucune entrée, même si elle est exécutée au premier plan. Elle n'est pas arrêtée, mais recevoir un code d'erreur ou EOF).
  • Il redirige la sortie standard et l'erreur standard vers le fichier Nohup.out, donc le programme n'échouera pas pour l'écriture sur la sortie standard si le terminal échoue, donc tout ce que le processus écrit n'est pas perdu.
  • Il empêche le processus de recevoir un SIGHUP (donc le nom).

Notez que Nohup ne pas supprime le processus du contrôle de travail du shell et ne le met pas en arrière-plan (mais comme un premier travail Nohup est plus ou moins inutile, vous le mettriez généralement en arrière-plan en utilisant &). Par exemple, contrairement à disown, le Shell vous indiquera quand même la tâche Nohup est terminée (sauf si le Shell est terminé avant, bien sûr).

Donc, pour résumer:

  • & met le travail en arrière-plan, c'est-à-dire le bloque lors de la tentative de lecture de l'entrée et empêche le shell d'attendre sa fin.
  • disown supprime le processus du contrôle des tâches du shell, mais le laisse toujours connecté au terminal. L'un des résultats est que le shell ne lui enverra pas de SIGHUP. De toute évidence, il ne peut être appliqué qu'aux travaux d'arrière-plan, car vous ne pouvez pas le saisir lorsqu'un travail de premier plan est en cours d'exécution.
  • Nohup déconnecte le processus du terminal, redirige sa sortie vers Nohup.out et le protège de SIGHUP. L'un des effets (celui de la dénomination) est que le processus ne recevra aucun SIGHUP envoyé. Il est complètement indépendant du contrôle des travaux et pourrait en principe être utilisé également pour les travaux de premier plan (bien que ce ne soit pas très utile).
595
celtschk

En utilisant & provoque l'exécution du programme en arrière-plan, vous obtiendrez donc une nouvelle invite du shell au lieu de bloquer jusqu'à la fin du programme. Nohup et disown sont largement 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é. Nohup le fait au début du travail. Si vous n'avez pas Nohup un travail au début, vous pouvez utiliser disown pour modifier un travail en cours d'exécution; sans argument, il modifie le travail en cours, qui est celui qui vient d'être mis en arrière-plan

174
Michael Mrozek

Voici mon expérience en essayant d'exécuter soffice en arrière-plan, en suivant une commande sans fin (par exemple tail). Pour cet exemple, j'utiliserai sleep 100.

&

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

I voir soffice logs/en appuyant sur Ctrl-C soffice s'arrête

Nohup .. &

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

I ne vois pas soffice logs/en appuyant sur Ctrl-C soffice s'arrête

& renier

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

I voir soffice logs/en appuyant sur Ctrl-C soffice s'arrête

setsid .. &

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

I voir soffice logs/en appuyant sur Ctrl-C soffice N'ARRÊTE PAS

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

9
Marinos An