2009-06-05 3 views

Répondre

64

La commande nohup est la façon d'exécuter un processus en tant que démon. Comme l'a noté Bruno Ranschaert, lorsque vous exécutez une commande dans un shell interactif, il dispose d'un terminal de contrôle et reçoit un signal SIGHUP (raccrochage) lorsque le processus de contrôle (généralement votre shell de connexion) se termine. La commande nohup prend des dispositions pour que l'entrée provienne de /dev/null et pour que la sortie et les erreurs passent à nohup.out, et pour que le programme ignore les interruptions, les signaux de sortie et les interruptions. Il a toujours le même terminal de contrôle - il ignore simplement les commandes des terminaux. Notez que si vous voulez que le processus s'exécute en arrière-plan, vous devez indiquer au shell de l'exécuter en arrière-plan - au moins sous Solaris (c'est-à-dire que vous tapez 'nohup sleep 20 &') sans l'esperluette premier plan).

Généralement, un processus exécuté via nohup est quelque chose qui prend du temps, mais qui ne traîne pas en attente d'une interaction venant d'ailleurs.

Typiquement (ce qui signifie que si vous essayez de trouver des exceptions à ces règles), un processus démon est quelque chose qui se cache en arrière-plan, déconnecté de tout terminal, mais attendant de répondre à une entrée quelconque. Les démons réseau attendent que les demandes de connexion ou les messages UDP arrivent sur le réseau, effectuent le travail approprié et envoient une réponse à nouveau. Pensez à un serveur Web, par exemple, ou à un SGBD.

Lorsqu'un processus se démonise complètement, il passe par certaines des étapes que le code nohup traverse; il réorganise ses E/S de sorte qu'il n'est pas connecté à un terminal, se détache du groupe de processus, ignore les signaux appropriés (ce qui pourrait signifier qu'il n'ignore aucun signal, puisqu'il n'y a pas de terminal pour lui envoyer les signaux générés via un terminal). Généralement, il se fend une fois et le parent se termine avec succès. Le processus fils se répète généralement une deuxième fois, après avoir réparé son groupe de processus et son ID de session, etc. l'enfant sort alors aussi. Le processus petit-enfant est maintenant autonome et n'apparaîtra pas dans la sortie ps pour le terminal où il a été lancé.

Vous pouvez regarder Advanced Programming in the Unix Environment, 3rd Edn par W Richard Stevens et Stephen A Rago, ou au Advanced Unix Programming, 2nd Edn par Marc J Rochkind pour des discussions de démonisation.

J'ai un programme daemonize qui va démoniser un programme qui ne sait pas comment se démoniser (correctement). Il a été écrit pour contourner les défauts d'un programme qui était supposé se démoniser mais qui n'a pas fait le travail correctement. Contactez-moi si vous le souhaitez - voir mon profil.

+11

Vous ne savez pas pourquoi vous l'appelez pauvre. Il fait la bonne chose si vous voulez faire de votre processus un démon, à part qu'il ne se déconnecte pas du terminal de contrôle, ce qui, en pratique, n'a pas d'importance. Deuxièmement, vous l'appelez faux, la forme correcte est '(nohup sleep 20 &)', c'est-à-dire que parens le déconnecte du chef de groupe de processus, afin qu'il ne reçoive pas de signaux pour ce groupe de processus. –

+0

@MaximYegorushkin Les parens ne font aucune différence (autant que je puisse le voir). Exécuter un programme à partir d'un shell fait toujours de ce prog un chef de groupe. Essayez ceci et vous verrez que le PGID correspond toujours au PID: 'perl -e 'system" ps -fjp $$ "''. En outre, l'esperluette n'est pas inhérente à nohup, donc même c'est une différence entre nohup et démon. Je vais ajouter ma propre réponse avec encore plus de différences. – Kelvin

+4

@Kelvin: Les parenthèses dans '(nohup sleep 20 &)' font vraiment la différence. Ils spécifient un sous-shell. À l'intérieur du sous-shell, la commande 'nohup' exécute la commande' sleep' en arrière-plan. Quand il revient, le sous-shell se ferme, donc 'sleep' est orphelin, n'est plus 'possédé' par le shell actuel. –

6

Dans les variantes UNIX, un processus est associé à un processus de terminal (shell de connexion). Ainsi, lorsque le processus terminal se termine, le processus est également interrompu à cause de cette association. Le nohup empêche la sortie d'un processus lorsque le terminal s'arrête. Un démon ou démon est un processus démarré par le système au démarrage, il s'exécute jusqu'à l'arrêt, aucun utilisateur ne le demande explicitement. Par définition, il ne fait pas partie d'une interaction utilisateur mais appartient au système.

Si vous avez accès au système en tant qu'utilisateur, vous pouvez utiliser nohup. Si vous êtes sysadmin, vous pouvez installer un processus deamon. Pour le processus, cela n'a pas d'importance.

+0

+1 Je suis corrigé. Mélangé entre daemon et un processus d'arrière-plan (&). :) – pugmarx

+1

Presque à droite. Lorsqu'un processus de contrôle (chef de groupe) quitte tous les processus du groupe, SIGHUP est éventuellement suivi de SIGCONT. –

+5

Quelques corrections: Un démon n'a pas besoin d'être un processus système; un utilisateur non privilégié peut exécuter un démon. Un utilisateur peut interagir avec un démon, mais pas via les signaux terminaux et les flux d'E/S (pensez serveur web). Les démons peuvent être démarrés presque n'importe quand; ils ne sont pas limités au démarrage du système. – Kelvin

-1

Un démon ne peut pas être lancé, tandis que nohup est lancé par l'utilisateur.

36

Devenir un démon

Ce lien a une bonne liste des étapes d'un processus devrait prendre pour devenir un démon: http://www.steve.org.uk/Reference/Unix/faq_2.html#SEC16

Je ne peux pas copier la liste in extenso en raison du droit d'auteur (voir a propos de la section), mais voici le résumé:

  1. fork (première fois) - donc nous ne sommes pas un chef de groupe, et que la sortie de parent.
  2. appel setsid() - pour devenir le leader d'une nouvelle session. Cet appel ne fonctionne que si nous ne sommes pas un chef de groupe. Cette nouvelle session n'a pas de terminal de contrôle. (Seconde fois) - nous ne sommes donc pas un leader de session (et donc ne pouvons pas retrouver un terminal de contrôle), et laissons le parent sortir.
  3. cd au répertoire racine - afin que nous n'empêchions pas d'autres répertoires d'être démontés.
  4. définir umask à la valeur désirée (facultatif) - parce que nous aurions pu hériter d'un masque que nous ne voulions pas.
  5. près stdin, stdout, stderr (ou tout simplement les rouvrir au point ailleurs)

nohup

Qu'est-ce nohup fait:

  • Si stdout et stderr sont reliées à une borne , les redirige vers nohup.out
  • ignore SIGHUP

Similitudes et différences

Remarquez comment les seules actions communes redirigez stdout et stderr. Être un démon ne nécessite même pas d'ignorer SIGHUP. '

nohup ne nécessite pas d'utiliser' & 'pour mettre en arrière-plan le processus - ce qui signifie que vous pouvez toujours utiliser ctrl-c pour envoyer SIGINT. Le processus répond toujours à l'entrée au clavier. Il ne change pas automatiquement stdin, il est donc recommandé de le faire vous-même via "< /dev/null".

Veuillez ne pas confondre nohup avec d'autres caractéristiques normalement utilisées avec celui-ci (par exemple, l'arrière-plan). Le PO a spécifiquement demandé nohup.

En pratique

En termes de pratique, lorsque vous voulez démarrer un processus de longue durée unique qui devrait se poursuivre lorsque les sorties de shell, vous aurez envie d'utiliser nohup, mais vous veulent aussi le combiner avec backgrounding et redirection de stdin.Un travail ponctuel ne vaut pas la peine de créer un démon, mais certaines propriétés d'un démon peuvent toujours être utiles avec un travail nohup, comme "cd /".

Les tâches périodiques sur un horaire régulier sont mieux exécutées via cron (ou un autre planificateur). Les démons sont les mieux adaptés pour superviser des tâches répétées qui n'ont pas une heure de début prévisible. Il n'y a normalement pas d'heure de fin définie pour le processus démon (elle est explicitement arrêtée par un utilisateur/un autre processus ou par un arrêt du système). Souvent, les démons sont des services qui répondent aux applications (clients) ou à d'autres conditions (par exemple, les données entrantes via un périphérique IO via unix select()). D'autres démons interrogent une condition et exécutent une action en réponse.

Addendum au sujet terminal de contrôle

Voir this page. Un résumé rapide est qu'un terminal de contrôle accorde un accès illimité à son stdin, stdout, stderr. Un seul groupe de processus peut avoir accès à stdin. Par défaut, les groupes de processus d'arrière-plan peuvent également écrire dans stdout et stderr. En outre, il semble que les signaux de clavier envoyés à un terminal sont uniquement envoyés au groupe de processus qui en est le terminal de contrôle.

+0

Votre lien steve.org.uk est cassé. – QED

Questions connexes