2011-11-14 10 views
21

Tengo un script de Perl que deseo demonizar. Básicamente, este script perl leerá un directorio cada 30 segundos, leerá los archivos que encuentre y luego procesará los datos. Para mantenerlo simple aquí considerar el siguiente script Perl (llamado synpipe_server, hay un enlace simbólico de este script en /usr/sbin/):Llamar a daemon en un script /etc/init.d es de bloqueo, no se está ejecutando en segundo plano

#!/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, básicamente, este script imprime algo cada 3 segundos.

Entonces, como yo quiero demonizar este script, también he puesto este script bash (también llamado 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 tengo bien entendido el doc para el demonio) el script de Perl debe ejecutarse en segundo plano y la salida debe ser redirigido a /dev/null si ejecuto:

service synpipe_server start 

Pero aquí es lo que me pasa en su lugar:

[[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]# 

Comienza el script de Perl pero lo ejecuta sin separarlo de la sesión del terminal actual, y puedo ver el resultado impreso en mi consola ... que no es realmente lo que esperaba. Además, el archivo PID está vacío (o solo con un avance de línea, ningún pid devuelto por daemon).

¿Alguien tiene alguna idea de lo que estoy haciendo mal?

EDITAR: quizás debería decir que estoy en una máquina de Red Hat.

Scientific Linux SL release 5.4 (Boron) 

Gracias, , Tony

+3

En lugar de escribir un demonio para sondear los cambios, se puede utilizar inotify http://en.wikipedia.org/wiki/Inotify para informarle cuando un cambio pasó. Es más fácil codificar, más eficiente y puede ver las actualizaciones más rápido. Hay una serie de módulos de CPAN para hablar con él. http://search.cpan.org/search?query=inotify&mode=all – Schwern

+0

Gracias, esta es información útil, definitivamente echaré un vistazo a Inotify. – tony

+0

@Schwern: eso no cambia el hecho de que tengo que ejecutar un daemon en segundo plano esperando notificaciones de inotify, ¿no? – tony

Respuesta

15

que finalmente volvió a escribir el iniciar la función en el script bash init, y no estoy usando daemon más.

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 
} 

Compruebo que el archivo pid ya no existe (de ser así, solo escriba una advertencia). Si no, uso

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

para iniciar la secuencia de comandos.

No sé si es seguro de esta manera (?) Pero funciona.

+2

Utilicé algo similar, pero usé 'daemon' junto a nohup para proporcionar el resultado que se muestra cuando se inició el script. Es más una señal visual que cualquier otra cosa, ya que el mensaje [OK] siempre volverá como OK siempre que nohup se haya ejecutado: 'daemon" nohup $ {exe}>/dev/null 2> & 1 & "' como un ejemplo. – Rohaq

+0

tony, ¿no moriría este daemon cuando termine tu caparazón? ¿O nohup prevenir eso? – Mark

+0

Sí, cuando el shell finaliza, el proceso creado por nohup permanece activo. – tony

0

Según man daemon sintaxis correcta es

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

Su guión de inicio de inicio debe ejecutar algo como:

daemon --pidfile ${pidfile} -- ${exe} 
+3

Gracias yko, pero no es esto porque mi uso 'daemon' dice: 'daemon [+/- nicelevel] {program}'. Tal vez no tenemos la misma versión. – tony

+0

@tony ¿Pudo resolver el problema del uso de los comandos? –

+0

@tony Terminé instalando [daemon de libslack] (http://libslack.org/daemon/#download) –

0

Como dijo here, parece que el proceso debe enviarse a segundo plano usando &. Daemon no lo haga por ti.

1

La forma correcta de demonizar un proceso es hacer que se separe del terminal por sí mismo. Así es como la mayoría de las suites de software más grandes lo hacen, por ejemplo, apache.

La razón de ser de daemon no hacer lo que se puede esperar de su nombre, y cómo hacer que un proceso UNIX separar a un segundo plano, se puede encontrar here en la sección 1.7 ¿Cómo hago para que mi programa para actuar como un demonio?

simplemente invocando un programa en el fondo no es realmente adecuado para estos programas de larga duración; que no separa correctamente el proceso de la sesión del terminal que lo inició. Además, la forma convencional de iniciar daemons es simplemente emitir el comando manualmente o desde un script rc; Se espera que el daemon ponga en sí en segundo plano.

Para leer más sobre este tema: What's the difference between nohup and a daemon?

Cuestiones relacionadas