J'ai un script Perl que je veux démoniser. Fondamentalement, ce script Perl lit un répertoire toutes les 30 secondes, lit les fichiers qu’il trouve et traite les données. Pour simplifier, considérez le script Perl suivant (appelé synpipe_server, il existe 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;
}
Donc, ce script imprime fondamentalement quelque chose toutes les 3 secondes.
Ensuite, comme je veux démoniser ce script, j'ai également placé 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 documentation pour le démon), le script Perl devrait être exécuté en arrière-plan et le résultat devrait être redirigé vers /dev/null
si j'exécute:
service synpipe_server start
Mais voici ce que je reçois à 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 lance le script Perl mais l'exécute sans le détacher de la session de terminal en cours, et je peux voir le résultat imprimé dans ma console ... ce qui n'est pas vraiment ce à quoi je m'attendais. De plus, le fichier PID est vide (ou avec un saut de ligne uniquement, pas de pid renvoyé par daemon ).
Est-ce que quelqu'un a 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)
Merci, Tony
J'ai finalement réécrit la fonction de démarrage dans le script bash init, et je n'utilise plus daemon
.
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
}
Je vérifie que le fichier pid n’existe pas déjà (le cas échéant, écrivez simplement un avertissement). Si non, j'utilise
Nohup ${exe} >/dev/null 2>&1 &
pour lancer le script.
Je ne sais pas si c'est sûr comme ça (?) Mais ça marche.
La bonne façon de démoniser un processus consiste à le détacher du terminal par lui-même. C’est ce que font la plupart des suites logicielles plus importantes, par exemple Apache .
La raison pour laquelle daemon
ne fait pas ce que vous attendez de son nom et explique comment détacher un processus unix en arrière-plan peut être trouvée ici dans la section 1.7 démon?
Invoquer un programme en arrière-plan n'est pas vraiment approprié pour ces programmes de longue durée; cela ne détache pas correctement le processus de la session de terminal qui l'a démarré. Également La méthode conventionnelle de démarrage des démons consiste simplement à lancer la commande manuellement ou à partir d'un script rc; le démon est censé mettre lui-même dans le fond.
Pour en savoir plus sur ce sujet: Quelle est la différence entre Nohup et un démon?
Selon man daemon
, la syntaxe correcte est
daemon [options] -- [command] [command args]
Le démarrage de votre script d'initialisation devrait exécuter quelque chose comme:
daemon --pidfile ${pidfile} -- ${exe}