web-dev-qa-db-fra.com

Comment puis-je exécuter un script Perl en tant que démon système sous Linux?

Quel est un moyen simple de faire fonctionner un script Perl en tant que démon sous Linux?

Actuellement, c'est sur CentOS. Je voudrais qu'il démarre avec le système et s'arrête avec le système, donc certains /etc/rc.d/init.d l'intégration serait aussi bien, mais je pourrais toujours ajouter une ligne personnalisée à /etc/rc.d/rc.local.

57
jedihawk

La façon la plus simple est d'utiliser 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
}

Alternativement, vous pouvez faire toutes les choses que Proc :: Daemon fait:

  1. Fourchez un enfant et quitte le processus parent.
  2. Devenez un chef de session (qui détache le programme du terminal de contrôle).
  3. Forkez un autre processus enfant et quittez le premier enfant. Cela empêche le potentiel d'acquérir un terminal de contrôle.
  4. Remplacez le répertoire de travail actuel par "/".
  5. Effacez le masque de création de fichier.
  6. Fermez tous les descripteurs de fichiers ouverts.

L'intégration au système runlevel est facile. Vous avez besoin d'un script comme celui-ci (remplacez XXXXXXXXXXXX par le nom du script Perl, YYYYYYYYYYYYYYYYYYY avec une description de ce qu'il fait et /path/to avec le chemin du script Perl) dans /etc/init.d. Puisque vous utilisez CentOS, une fois que vous avez le script dans /etc/init.d, vous pouvez simplement utiliser chkconfig pour le désactiver ou l'activer dans les différents niveaux d'exécution.

#!/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
82
Chas. Owens

Si vous n'avez pas Proc :: Daemon comme suggéré par Chas. Owens, voici comment vous le feriez à la main:

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");
 }
40
Bklyn

Je pense que la façon la plus simple est d'utiliser démon . Il vous permet d'exécuter n'importe quel processus en tant que démon. Cela signifie que vous n'avez pas à vous soucier des bibliothèques si, par exemple, vous avez décidé de passer en python. Pour l'utiliser, utilisez simplement:

daemon myscript args

Cela devrait être disponible sur la plupart des distributions, mais il pourrait ne pas être installé par défaut.

7
Zifre