I have a Perl script that I want to daemonize. Basically this perl script will read a directory every 30 seconds, read the files that it finds and then process the data. To keep it simple here consider the following Perl script (called synpipe_server, there is a symbolic link of this script in /usr/sbin/
) :
#!/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;
}
So this script basically prints something every 3 seconds.
Then, as I want to daemonize this script, I've also put this bash script (also called synpipe_server) in /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
So, (if I have well understood the doc for daemon) the Perl script should run in the background and the output should be redirected to /dev/null
if I execute :
service synpipe_server start
But here is what I get instead :
[root@master 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 ]
[root@master init.d]#
So it starts the Perl script but runs it without detaching it from the current terminal session, and I can see the output printed in my console ... which is not really what I was expecting. Moreover, the PID file is empty (or with a line feed only, no pid returned by daemon).
Does anyone have any idea of what I am doing wrong ?
EDIT : maybe I should say that I am on a Red Hat machine.
Scientific Linux SL release 5.4 (Boron)
Thanks, Tony
I finally re-wrote the start function in the bash init script, and I am not using daemon
anymore.
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
}
I check that the pid file is not existing already (if so, just write a warning). If not, I use
nohup ${exe} >/dev/null 2>&1 &
to start the script.
I don't know if it is safe this way (?) but it works.
The proper way to daemonize a process is have it detach from the terminal by itself. This is how most larger software suites do it, for instance, apache.
The rationale behind daemon
not doing what you would expect from its name, and how to make a unix process detach into the background, can be found here in section 1.7 How do I get my program to act like a daemon?
Simply invoking a program in the background isn't really adequate for these long-running programs; that does not correctly detach the process from the terminal session that started it. Also, the conventional way of starting daemons is simply to issue the command manually or from an rc script; the daemon is expected to put itself into the background.
For further reading on this topic: What's the difference between nohup and a daemon?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With