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
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.
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?
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}