Quelle est la différence entre le démon start-stop et l'exécution avec &?

18

J'installe un service dans /etc/init.d. Je regarde divers scripts là-dedans, certains sont implémentés avec start-stop-daemon ...et d'autres avec /path/to/script &.

Tous enregistrent le pid dans un fichier et font quelques vérifications.

Quelle est la meilleure pratique, quelles sont les différences, qu'est-ce qu'il est important de savoir ici ...? (en général)

Dans mon cas particulier, j'ai un simple serveur http localhost léger en Java qu'une application appellera une fois toutes les heures environ et il donne juste un nombre aléatoire stupide (pas plus de détails ici, je veux simplement dire qu'il n'utilise pas le système de fichiers ou fils ou quelque chose de compliqué au cas où cette question dans ma question)

Merci

Thomas
la source

Réponses:

27

Un travail en arrière-plan (c'est-à-dire commencé par &) a toujours ses stdin, stdout et stderr connectés au terminal dans lequel il a été démarré. Il peut soudainement écrire (par exemple des messages d'erreur) sur le terminal ("perturber" le travail dans le avant-plan) ou suspendre l’attente de l’entrée du clavier (vous devez d’abord la mettre Vous pouvez bien sûr rediriger stdout et stderr vers un fichier ou vers / dev / null pour empêcher le job d'arrière-plan d'écrire sur le terminal.

Un job d'arrière-plan peut également être mis au premier plan - par exemple. la tâche de premier plan actuelle est arrêtée et la fgcommande (premier plan) est utilisée pour placer une tâche de fond au premier plan. Un travail d'arrière-plan peut également être atteint par des signaux provenant du terminal - par exemple. SIGHUP lorsque vous fermez le terminal, qui termine généralement (la plupart) les programmes démarrés dans le terminal.

Un démon - comme ceux démarrés automatiquement par init.d, mais qui peut également être démarré manuellement à partir d'un terminal - d'autre part, s'exécute déconnecté de tous les terminaux. Même s'il a été démarré manuellement à partir d'un terminal, un démon sera déconnecté du terminal, il ne pourra donc ni l'écrire (stdout, stderr) ni le lire (stdin). Il est également "à l'abri" des signaux envoyés "automatiquement" par le terminal. (bien que vous puissiez lui envoyer des signaux en utilisant kill -signal pid).

"Contexte" et "premier plan" se réfèrent à l'état du processus pour un terminal - que ce soit le processus contrôlant actuellement le terminal ou non. Étant donné que les démons ne sont pas connectés à un terminal (mais qu'ils en ont été déconnectés avec précaution de toutes les manières), on ne peut donc pas dire qu'il fonctionne en arrière-plan. Les démons ne sont que des processeurs exécutés sans être associés à un terminal - ni en avant-plan ni en arrière-plan.

Si vous utilisez psles options qui indique les utilisations des processus d' un terminal, vous verrez que les deux avant et backgroundjobs sont assosciated avec un terminal (par exemple. Tty2). Les démons, d'autre part, ont un "?" dans ce champ.

Les démons se comportent généralement comme tels, même s'ils sont démarrés manuellement. La création de votre propre démon, est un peu de travail - il y a quelques trucs impliqués pour le déconnecter totalement du terminal. Vous devez créer son propre utilisateur / groupe pour fonctionner en tant que. Vous devez généralement utiliser / tmp, / var / tmp ou / var / run si vous voulez qu'il crée des fichiers - il ne devrait généralement pas avoir de droits ailleurs. Comme il ne peut pas signaler d'erreurs à un terminal, vous devriez le faire écrire dans un fichier journal (par exemple, c'est son propre fichier journal dans / var / log). Les démons devraient faire une entrée dans / var / run avec son PID actuel, et devraient vérifier si une autre instance de celui-ci était déjà en cours d'exécution. Il doit respecter les verrous (/ var / lock) pour les fichiers ou les périphériques, le cas échéant. Il devrait répondre à SIGHUP en rechargeant ses fichiers de configuration et utiliser des configurations mises à jour.

Un autre point est le fonctionnement de la plupart des démons. Un démon est généralement un exécutable unique qui peut s'exécuter dans l'un des deux modes distincts; selon qu'il s'agit du démon d'origine - le parent - démarré au démarrage ou manuellement ... ou d'un enfant engendré par ce parent. Le processus parent est généralement juste assis et attend un événement - une heure spécifique, un temps écoulé, une tentative de connexion à un port réseau spécifique, ou quoi que ce soit. Lorsque cela se produit, le parent crée un processus enfant identique à lui-même (en utilisant l'appel système fork ()) - et recommence immédiatement à attendre un autre événement (et peut-être à générer plus d'enfants). C'est le processus enfant qui fera le travail - comme la synchronisation d'un disque, l'exécution d'une commande (par exemple cron) ou l'établissement d'une connexion réseau (par exemple sshdouftpd). La seule différence entre le parent et l'enfant, c'est qu'ils ont obtenu des PID différents et que le PPID (Parent-PID) de l'enfant est le PID du processus parent - cela peut être utilisé pour déterminer si le processus est le parent ou l'enfant. Le même processus doit donc pouvoir fonctionner selon deux modes - en tant que parent en attente (et en train de se reproduire), ou en tant qu'enfant qui travaille.

Bien qu'il ne soit pas difficile d'écrire un démon, ce n'est pas trivial non plus - comme vous le voyez, il y a pas mal de "trucs" que vous devez d'abord connaître. En général, je pense que l'écriture d'un démon nécessiterait beaucoup d'efforts pour un gain très faible par rapport à d'autres alternatives:

Utiliser nohupou disownsur un travail en arrière-plan est généralement une bonne alternative, car il maintient le processus en vie même si le terminal se ferme. C'est souvent une bonne idée de rediriger stdout et stderr vers un fichier ou vers / dev / null. Pour des programmes plus interactifs, screenc'est un bon moyen de ranger quelque chose "de côté" jusqu'à ce que vous en ayez besoin. at, batchet crontabvaut également la peine d'être pris en considération.

Baard Kopperud
la source
1
Je me souviens aussi de mes anciens cours sur le système Unix, que lorsqu'il est lancé depuis un terminal, le serveur doit également quitter son [groupe de processus] [ en.wikipedia.org/wiki/Process_group] . Autant que je m'en souvienne. Pour que le processus soit immunisé contre tout signal provenant de son terminal d'origine.
yves Baumes