L'appel au démon dans un script /etc/init.d bloque, ne s'exécute pas en arrière-plan

9

J'ai un script Perl que je veux démonifier. Fondamentalement, ce script perl lira un répertoire toutes les 30 secondes, lira les fichiers qu'il trouve et traitera les données. Pour rester simple ici, considérons le script Perl suivant (appelé synpipe_server, il y a un lien symbolique de ce script dans /usr/sbin/):

#!/usr/bin/perl
use strict;
use warnings;

my $continue = 1;
$SIG{'TERM'}  = sub { $continue = 0; print "Caught TERM signal\n"; };
$SIG{'INT'} = sub { $continue = 0; print "Caught INT signal\n"; };

my $i = 0;
while ($continue) {
     #do stuff
     print "Hello, I am running " . ++$i . "\n";
     sleep 3;
}

Ce script imprime donc quelque chose toutes les 3 secondes.

Ensuite, comme je veux démonifier ce script, j'ai également mis ce script bash (également appelé synpipe_server) dans /etc/init.d/:

#!/bin/bash
# synpipe_server : This starts and stops synpipe_server
#
# chkconfig: 12345 12 88
# description: Monitors all production pipelines
# processname: synpipe_server
# pidfile: /var/run/synpipe_server.pid
# Source function library.
. /etc/rc.d/init.d/functions

pname="synpipe_server"
exe="/usr/sbin/synpipe_server"
pidfile="/var/run/${pname}.pid"
lockfile="/var/lock/subsys/${pname}"

[ -x $exe ] || exit 0

RETVAL=0

start() {
    echo -n "Starting $pname : "
    daemon ${exe}
    RETVAL=$?
    PID=$!
    echo
    [ $RETVAL -eq 0 ] && touch ${lockfile}
    echo $PID > ${pidfile}
}

stop() {
    echo -n "Shutting down $pname : "
    killproc ${exe}
    RETVAL=$?
    echo
    if [ $RETVAL -eq 0 ]; then
        rm -f ${lockfile}
        rm -f ${pidfile}
    fi
}

restart() {
    echo -n "Restarting $pname : "
    stop
    sleep 2
    start
}

case "$1" in
    start)
        start
    ;;
    stop)
        stop
    ;;
    status)
        status ${pname}
    ;;
    restart)
        restart
    ;;
    *)
        echo "Usage: $0 {start|stop|status|restart}"
    ;; esac

exit 0

Donc, (si j'ai bien compris la doc pour le démon), le script Perl devrait s'exécuter en arrière-plan et la sortie devrait être redirigée /dev/nullsi j'exécute:

service synpipe_server start

Mais voici ce que j'obtiens à la place:

[root@master init.d]# service synpipe_server start
Starting synpipe_server : Hello, I am running 1
Hello, I am running 2
Hello, I am running 3
Hello, I am running 4
Caught INT signal
                                                           [  OK  ]
[root@master init.d]# 

Donc, il démarre le script Perl mais l'exécute sans le détacher de la session terminale actuelle, et je peux voir la sortie imprimée dans ma console ... ce qui n'est pas vraiment ce que j'attendais. De plus, le fichier PID est vide (ou avec un saut de ligne uniquement, aucun pid retourné par le démon ).

Quelqu'un at-il une idée de ce que je fais mal?

EDIT: je devrais peut-être dire que je suis sur une machine Red Hat.

Scientific Linux SL release 5.4 (Boron)

Est-ce que cela ferait l'affaire si au lieu d'utiliser la fonction démon, j'utilise quelque chose comme:

nohup ${exe} >/dev/null 2>&1 &

dans le script init?

Tony
la source

Réponses:

4

Je vous suggère de démonifier le script perl directement au lieu d'ajouter la couche supplémentaire de la daemonfonction de script d'initialisation redhat . Il est difficile d'obtenir les bons démons si vous essayez de les écrire vous-même. Proc :: Daemon est assez simple.

En outre, voici une discussion sur la façon d'écrire des démons perl .

Réponse bonus: utilisez daemontools et Proc :: Daemontools . Cela fournit un système de gestion de démon complet et vous avez probablement déjà installé daemontools de toute façon. Certaines personnes n'aiment pas daemontools mais cela fait le travail.

Peu importe le nombre de fois où j'écris un démon, cela semble toujours bizarre. Je devrais peut-être juste utiliser Dæmon.

Phil Hollenback
la source
2

Si vous utilisez Debian et ses dérivés, utilisez l' start-stop-daemonoption -b pour démarrer votre processus sans problème.

Dom
la source
Ceci est une machine RedHat, donc devrait utiliser daemonet à la killprocplace
MariuszS
1
Cela a résolu mon problème aujourd'hui. Dans Ubuntu, j'ai copié /etc/init.d/skeleton et je n'ai pas pu comprendre pourquoi il ne fonctionnait pas en arrière-plan. J'ai supposé qu'il était déjà configuré pour le fond, mais il s'avère que ce n'est pas le cas.
Ryan