linux - servicios - La llamada al daemon en un script/etc/init.d está bloqueando, no se está ejecutando en segundo plano
listar servicios linux (4)
Tengo un script de Perl que quiero demonizar. Básicamente, este script de Perl leerá un directorio cada 30 segundos, leerá los archivos que encuentre y luego procesará los datos. Para mantenerlo simple, considere el siguiente script de Perl (llamado synpipe_server, hay un enlace simbólico de este script en /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;
}
Así que este script básicamente imprime algo cada 3 segundos.
Luego, como quiero demonizar esta secuencia de comandos, también he puesto esta secuencia de comandos bash (también llamada synpipe_server) en /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
Por lo tanto, (si he entendido bien el documento para el daemon) el script Perl debería ejecutarse en segundo plano y la salida debería redirigirse a /dev/null
si ejecuto:
service synpipe_server start
Pero aquí es lo que obtengo en su lugar:
[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]#
Entonces comienza el script Perl pero lo ejecuta sin separarlo de la sesión actual del terminal, y puedo ver la salida impresa en mi consola ... que no es realmente lo que esperaba. Además, el archivo PID está vacío (o solo con un salto de línea, no hay un pid devuelto por el daemon ).
¿Alguien tiene alguna idea de lo que estoy haciendo mal?
EDITAR: tal vez debería decir que estoy en una máquina de Red Hat.
Scientific Linux SL release 5.4 (Boron)
Gracias Tony
Como se dijo here , parece que el proceso debe enviarse a un segundo plano utilizando &. Daemon no lo haga por ti.
Finalmente reescribí la función de inicio en el script de inicio de bash, y ya no estoy usando el 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
}
Verifico que el archivo pid ya no exista (si es así, simplemente escriba una advertencia). Si no, yo uso
nohup ${exe} >/dev/null 2>&1 &
para iniciar el guión.
No sé si es seguro de esta manera (?) Pero funciona.
La forma correcta de demonizar un proceso es separarlo del terminal por sí mismo . Así es como lo hacen los paquetes de software más grandes, por ejemplo, apache .
La razón detrás de que el daemon
no hace lo que se esperaría de su nombre, y cómo hacer que un proceso de Unix se separe del fondo, se puede encontrar here en la sección 1.7 ¿Cómo hago que mi programa actúe como un demonio?
Simplemente invocar un programa en segundo plano no es realmente adecuado para estos programas de larga ejecución; eso no separa correctamente el proceso de la sesión de terminal que lo inició. Además, la forma convencional de iniciar demonios es simplemente emitir el comando manualmente o desde un script rc; Se espera que el demonio se ponga en segundo plano.
Para leer más sobre este tema: ¿Cuál es la diferencia entre nohup y un daemon?
Según el man daemon
la sintaxis correcta es
daemon [options] -- [command] [command args]
El inicio de su script de inicio debería ejecutar algo como:
daemon --pidfile ${pidfile} -- ${exe}