У меня есть сценарий Perl, который я хочу демонизировать. Обычно этот сценарий perl будет читать каталог каждые 30 секунд, считывать файлы, которые он находит, а затем обрабатывать данные. Для простоты рассмотрим следующий Perl-скрипт (называемый synpipe_server, символьная ссылка на этот скрипт есть в /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;
}
Итак, этот скрипт в основном что-то печатает каждые 3 секунды.
Затем, поскольку я хочу демонизировать этот сценарий, я также поместил этот сценарий bash (также называемый synpipe_server) в /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
Итак (если я хорошо понял документацию для демона) сценарий Perl должен работать в фоновом режиме, а вывод должен быть перенаправлен на /dev/null
если я выполню:
service synpipe_server start
Но вот что я получаю вместо этого:
[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]#
Таким образом, он запускает сценарий Perl, но запускает его, не отделяя его от текущего сеанса терминала, и я могу видеть вывод, напечатанный в моей консоли ... что на самом деле не то, что я ожидал. Более того, файл PID пуст (или только с переводом строки, pid не возвращается демон).
Кто-нибудь знает, что я делаю не так?
РЕДАКТИРОВАТЬ: возможно, мне следует сказать, что я нахожусь на машине Red Hat.
Scientific Linux SL release 5.4 (Boron)
Сработает ли он, если вместо функции демона я использую что-то вроде:
nohup ${exe} >/dev/null 2>&1 &
в сценарии инициализации?
Я предлагаю вам демонизировать perl-скрипт напрямую, а не добавлять дополнительный уровень скрипта инициализации redhat daemon
функция. Трудно сделать демонов правильными, если вы попытаетесь написать их самостоятельно. Proc :: Демон довольно просто.
Кроме того, здесь обсуждается как писать демонов Perl.
Бонусный ответ: используйте DAEMON Tools и Proc :: Daemontools. Это обеспечивает комплексную систему управления демонами, и у вас, вероятно, уже установлены daemontools. Некоторым людям не нравятся инструменты демона, но он выполняет свою работу.
Сколько бы раз я ни писал, демон все равно кажется странным. Может мне стоит просто использовать деймона.
Если вы используете Debian и его производные, используйте start-stop-daemon
с параметром -b, чтобы запустить процесс без проблем.