Différence entre nohup, renie et &

Quelle est la différence entre

$ nohup foo 

et

 $ foo & 

et

 $ foo & $ disown 

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

  • Le process exécutant foo est créé.
  • Le process 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 process (ce qui entraîne normalement la fin du process).
  • Sinon, le shell attend (est bloqué) jusqu'à ce que le process se termine.

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

  • Le process exécutant foo est créé.
  • Le process hérite stdout / stderr du shell (donc il écrit toujours sur le terminal).
  • Le process hérite en principe de stdin, mais dès qu'il essaie de lire à partir de stdin, il est arrêté.
  • Il est mis dans la list des tâches de fond que le shell gère, ce qui signifie notamment:
    • Il est répertorié avec les jobs et peut être consulté en utilisant %n (où n est le numéro du travail).
    • Il peut être transformé en tâche de premier plan en utilisant fg , auquel cas il se poursuit comme si vous ne l'auriez pas utilisé (et s'il était arrêté en essayant de lire à partir d'une input standard, il peut maintenant lire le terminal ).
    • Si le shell a reçu un SIGHUP , il envoie également un SIGHUP au process. En fonction du shell et éventuellement des options définies pour le shell, lors de la terminaison du shell, il enverra également un SIGHUP au process.

Maintenant, disown supprimer le travail de la list des tâches du shell, tous les sous-points ci-dessus ne s'appliquent plus (y compris le process envoyé par le shell SIGHUP ). 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 terminant le SSH connection), le programme échouera dès qu'il essaiera de lire à partir de l'input standard ou d'écrire sur la sortie standard.

Ce que nohup fait d'autre part, c'est de séparer efficacement le process du terminal:

  • Il ferme l'input standard (le programme ne sera pas en mesure de lire n'importe quelle input, même si elle 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 file nohup.out , de sorte que le programme n'échoue pas pour l'écriture sur la sortie standard en cas de défaillance du terminal, de sorte que tout le process écrit n'est pas perdu.
  • Il empêche le process de recevoir un SIGHUP (donc le nom).

Notez que nohup ne supprime pas le process du contrôle de travail du shell et ne le met pas en arrière-plan (mais comme un job de premier plan est plus ou less inutile, vous le placez généralement en arrière-plan avec & ). Par exemple, contrairement à disown , le shell vous dira quand le job nohup est terminé (à less que le shell ne soit terminé avant, bien sûr).

Donc pour résumer:

  • & met le travail en arrière-plan, ce qui le rend bloquant lors de la tentative de lecture d'input, ce qui empêche le shell d'être terminé.
  • disown supprime le process du contrôle du travail du shell, mais le laisse toujours connecté au terminal. L'un des résultats est que le shell ne lui enverra pas un SIGHUP . Évidemment, il ne peut être appliqué qu'aux tâches d'arrière-plan, car vous ne pouvez pas l'entrer lorsqu'un travail de premier plan est en cours d'exécution.
  • nohup déconnecte le process du terminal, redirige sa sortie vers nohup.out et le protège de SIGHUP . L'un des effets (le nommage) est que le process ne recevra pas de NOHUP envoyé. Il est totalement indépendant du contrôle des travaux et pourrait en principe être utilisé également pour les travaux de premier plan (bien que cela ne soit pas très utile).

L'utilisation de & provoque l'exécution du programme en arrière-plan, de sorte que vous obtiendrez une nouvelle invite de shell au lieu de bloquer jusqu'à ce que le programme se termine. nohup et disown sont en grande partie sans rapport; ils suppriment les signaux SIGHUP (raccrochage) afin que le programme ne soit pas automatiquement tué lorsque le terminal de contrôle est fermé. nohup fait cela quand le travail commence. Si vous ne nohup pas un travail au démarrage, vous pouvez utiliser disown pour modifier un travail en cours; sans arguments, il modifie le travail en cours, qui est celui qui était juste en arrière-plan

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

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

Je vois les logs soffice / en appuyant sur Ctrl-C soffice s'arrête

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

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

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

Je vois les logs soffice / en appuyant sur Ctrl-C soffice s'arrête

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

Je vois soffice logs / en appuyant sur Ctrl-C soffice NE PAS ARRETER

Pour économiser de l'espace:
nohup setsid .. : n'affiche pas les logs / soffice NE STOPTE PAS sur Ctrl-C
nohup with & disown à la fin: n'indique pas les logs / soffice s'arrête sur Ctrl-C