web-dev-qa-db-de.com

Ein Aufruf an den Dämon in einem Skript /etc/init.d blockiert und wird nicht im Hintergrund ausgeführt

Ich habe ein Perl-Skript, das ich daemonisieren möchte. Grundsätzlich liest dieses Perl-Skript alle 30 Sekunden ein Verzeichnis, liest die gefundenen Dateien und verarbeitet die Daten. Um es einfach zu halten, betrachten Sie das folgende Perl-Skript (genannt synpipe_server, in /usr/sbin/ gibt es einen symbolischen Link zu diesem Skript):

#!/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;
}

Dieses Skript druckt also im Grunde alle 3 Sekunden etwas.

Dann, da ich dieses Skript dämonisieren möchte, habe ich dieses bash-Skript (auch als synpipe_server bezeichnet) in /etc/init.d/ eingefügt:

#!/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

(Wenn ich das doc für daemon gut verstanden habe) sollte das Perl-Skript im Hintergrund ausgeführt werden und die Ausgabe sollte zu /dev/null umgeleitet werden, wenn ich Folgendes ausführe:

service synpipe_server start

Aber hier bekomme ich stattdessen:

[[email protected] 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  ]
[[email protected] init.d]# 

Es startet also das Perl-Skript, führt es jedoch aus, ohne es von der aktuellen Terminalsitzung zu trennen, und ich kann die Ausgabe in meiner Konsole ausdrucken ... was nicht wirklich das war, was ich erwartet hatte. Außerdem ist die PID-Datei leer (oder nur mit einem Zeilenvorschub, keine von daemon zurückgegebene PID).

Hat jemand eine Ahnung, was ich falsch mache?

EDIT: Vielleicht sollte ich sagen, dass ich auf einer Red Hat-Maschine bin.

Scientific Linux SL release 5.4 (Boron)

Danke, Tony

22
tony

Schließlich habe ich die Startfunktion im Bash-Init-Skript neu geschrieben und benutze daemon nicht mehr.

start() {
    echo -n "Starting $pname : "
    #daemon ${exe} # Not working ...
    if [ -s ${pidfile} ]; then
       RETVAL=1
       echo -n "Already running !" && warning
       echo
    else
       Nohup ${exe} >/dev/null 2>&1 &
       RETVAL=$?
       PID=$!
       [ $RETVAL -eq 0 ] && touch ${lockfile} && success || failure
       echo
       echo $PID > ${pidfile}
    fi
}

Ich überprüfe, ob die PID-Datei noch nicht vorhanden ist (wenn ja, schreibe einfach eine Warnung). Wenn nicht, benutze ich 

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

um das Skript zu starten.

Ich weiß nicht, ob es auf diese Weise sicher ist (?), Aber es funktioniert.

16
tony

Der richtige Weg, um einen Prozess zu dämonisieren, besteht darin, ihn vom Terminal von sich selbst zu trennen. So machen es die meisten größeren Software-Suites, zum Beispiel Apache .

Die Gründe dafür, dass daemon nicht das tut, was Sie von ihrem Namen erwarten würden, und wie man einen Unix-Prozess in den Hintergrund trennt, ist hier in Abschnitt 1.7 ?

Das einfache Aufrufen eines Programms im Hintergrund ist für .__ nicht wirklich ausreichend. diese lang laufenden Programme; das löst nicht richtig die Prozess von der Terminalsitzung, die es gestartet hat. Auch die Eine herkömmliche Methode zum Starten von Dämonen besteht einfach darin, den Befehl manuell oder aus einem RC-Skript; Es wird erwartet, dass der Dämon selbst .__ setzt. in den hintergrund.

Weitere Informationen zu diesem Thema: Was ist der Unterschied zwischen Nohup und einem Dämon?

2
MarkM

Laut man daemon ist die korrekte Syntax

daemon [options] -- [command] [command args]

Ihr Init-Skript-Start sollte etwa wie folgt ausgeführt werden:

daemon --pidfile ${pidfile} -- ${exe}
0
yko