Search code examples
linuxperlstartupdaemonshutdown

How can I run a Perl script as a system daemon in linux?


What's a simple way to get a Perl script to run as a daemon in linux?

Currently, this is on CentOS. I'd want it to start up with the system and shutdown with the system, so some /etc/rc.d/init.d integration would also be nice, but I could always add a custom line to /etc/rc.d/rc.local.


Solution

  • The easiest way is to use 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
    }
    

    Alternately you could do all of the things Proc::Daemon does:

    1. Fork a child and exits the parent process.
    2. Become a session leader (which detaches the program from the controlling terminal).
    3. Fork another child process and exit first child. This prevents the potential of acquiring a controlling terminal.
    4. Change the current working directory to "/".
    5. Clear the file creation mask.
    6. Close all open file descriptors.

    Integrating with the runlevel system is easy. You need a script like the following (replace XXXXXXXXXXXX with the Perl script's name, YYYYYYYYYYYYYYYYYYY with a description of what it does, and /path/to with path to the Perl script) in /etc/init.d. Since you are using CentOS, once you have the script in /etc/init.d, you can just use chkconfig to turn it off or on in the various runlevels.

    #!/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