How can I run a Perl script as a system daemon in linux?
The easiest way is to use Proc::Daemon.
#!/usr/bin/perluse 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:
- Fork a child and exits the parent process.
- Become a session leader (which detaches the program from the controlling terminal).
- Fork another child process and exit first child. This prevents the potential of acquiring a controlling terminal.
- Change the current working directory to
"/"
. - Clear the file creation mask.
- 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/functionsbinary="/path/to/XXXXXXXXXXXX"[ -x $binary ] || exit 0RETVAL=0start() { 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}" ;;esacexit 0
If you don't have Proc::Daemon as suggested by Chas. Owens, here's how you'd do it by hand:
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"); }
I think the easiest way is to use daemon. It allows you to run any process as a daemon. This means you don't have to worry about libraries if you, for example, decided to change to python. To use it, just use:
daemon myscript args
This should be available on most distros, but it might not be installed by default.