Вызов демону в скрипте /etc/init.d блокируется, не работает в фоновом режиме

9

У меня есть 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 &

в сценарии инициализации?

Тони
источник

Ответы:

4

Я предлагаю вам демонизировать скрипт perl напрямую, а не добавлять дополнительный слой daemonфункции скрипта redhat init . Трудно получить правильные демоны, если вы попытаетесь написать их самостоятельно. Proc :: Daemon довольно прост.

Также здесь обсуждается, как писать демоны Perl .

Бонусный ответ: используйте daemontools и Proc :: Daemontools . Это обеспечивает комплексную систему управления демонами, и вы, вероятно, уже установили daemontools. Некоторым людям не нравятся daemontools, но он выполняет свою работу.

Независимо от того, сколько раз я пишу демон, он все равно кажется странным. Может быть, я должен просто использовать DEMON.

Фил Холленбек
источник
2

Если вы используете Debian и его производные, используйте start-stop-daemonопцию -b, чтобы запустить ваш процесс без проблем.

Дом
источник
Это машина RedHat, поэтому следует использовать daemonи killprocвместо этого
MariuszS
1
Это решило мою проблему сегодня. В Ubuntu я скопировал /etc/init.d/skeleton и не мог понять, почему он не работает в фоновом режиме. Я предполагал, что это уже было настроено для фона, но оказывается, что это не так.
Райан