¿Cómo puedo ejecutar un script en Perl como un demonio del sistema en Linux?
Pregunta
¿Qué es una forma sencilla de obtener un script Perl para ejecutarse como un demonio en linux?
En la actualidad, esto es en CentOS. Me gustaría que se inicie con el sistema y el apagado con el sistema, por lo que algunos de integración /etc/rc.d/init.d
también estaría bien, pero siempre podría añadir una línea a medida para /etc/rc.d/rc.local
.
Solución
La forma más sencilla es utilizar Proc :: Daemon .
#!/usr/bin/perl
use strict;
use warnings;
use Proc::Daemon;
Proc::Daemon::Init;
my $continue = 1;
$SIG{TERM} = sub { $continue = 0 };
while ($continue) {
#do stuff
}
Como alternativa se podría hacer todas las cosas Proc :: daemon:
- Tenedor un niño y sale del proceso padre.
- Se convierte en lider de sesión (que separa el programa desde la terminal de control).
- Tenedor otro proceso hijo y salida primer hijo. Esto evita la posibilidad de adquirir un terminal de control.
- Cambiar el directorio de trabajo actual a
"/"
. - Borrar la máscara de creación de archivos.
- Cierre todos los descriptores de ficheros abiertos.
La integración con el sistema de nivel de ejecución es fácil. Es necesario un script como el siguiente (reemplace XXXXXXXXXXXX
con el nombre del script en Perl, YYYYYYYYYYYYYYYYYYY
con una descripción de lo que hace, y /path/to
con la ruta al script Perl) en /etc/init.d
. Dado que está utilizando CentOS, una vez que tenga la secuencia de comandos en /etc/init.d
, sólo puede utilizar chkconfig para apagarlo o en los distintos niveles de ejecución.
#!/bin/bash
#
# XXXXXXXXXXXX This starts and stops XXXXXXXXXXXX
#
# chkconfig: 2345 12 88
# description: XXXXXXXXXXXX is YYYYYYYYYYYYYYYYYYY
# processname: XXXXXXXXXXXX
# pidfile: /var/run/XXXXXXXXXXXX.pid
### BEGIN INIT INFO
# Provides: $XXXXXXXXXXXX
### END INIT INFO
# Source function library.
. /etc/init.d/functions
binary="/path/to/XXXXXXXXXXXX"
[ -x $binary ] || exit 0
RETVAL=0
start() {
echo -n "Starting XXXXXXXXXXXX: "
daemon $binary
RETVAL=$?
PID=$!
echo
[ $RETVAL -eq 0 ] && touch /var/lock/subsys/XXXXXXXXXXXX
echo $PID > /var/run/XXXXXXXXXXXX.pid
}
stop() {
echo -n "Shutting down XXXXXXXXXXXX: "
killproc XXXXXXXXXXXX
RETVAL=$?
echo
if [ $RETVAL -eq 0 ]; then
rm -f /var/lock/subsys/XXXXXXXXXXXX
rm -f /var/run/XXXXXXXXXXXX.pid
fi
}
restart() {
echo -n "Restarting XXXXXXXXXXXX: "
stop
sleep 2
start
}
case "$1" in
start)
start
;;
stop)
stop
;;
status)
status XXXXXXXXXXXX
;;
restart)
restart
;;
*)
echo "Usage: $0 {start|stop|status|restart}"
;;
esac
exit 0
Otros consejos
Si usted no tiene Proc: : Daemon como se sugiere por Chas. Owens, así es como usted lo haría con la mano:
sub daemonize {
use POSIX;
POSIX::setsid or die "setsid: $!";
my $pid = fork() // die $!; #//
exit(0) if $pid;
chdir "/";
umask 0;
for (0 .. (POSIX::sysconf (&POSIX::_SC_OPEN_MAX) || 1024))
{ POSIX::close $_ }
open (STDIN, "</dev/null");
open (STDOUT, ">/dev/null");
open (STDERR, ">&STDOUT");
}
Creo que la forma más sencilla es utilizar demonio . Se le permite ejecutar cualquier proceso como un demonio. Esto significa que usted no tiene que preocuparse acerca de las bibliotecas si, por ejemplo, decidió cambiar a Python. Para usarlo, sólo tiene que utilizar:
daemon myscript args
Esto debería estar disponible en la mayoría de distribuciones, pero no pudo ser instalado por defecto.