在/etc/init.d脚本中调用守护进程是阻塞的,而不是在后台运行

我有一个Perl脚本,我想要守护进程。 基本上这个perl脚本会每隔30秒读取一个目录,读取它find的文件,然后处理数据。 为了简单起见,可以考虑下面的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脚本应该在后台运行,输出应该被redirect到/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脚本,但运行它,而不会从当前的terminal会话中分离它,我可以看到输出打印在我的控制台中…这不是我所期待的。 而且,PID文件是空的(或者只有一个换行符, 守护进程没有返回pid)。

有谁知道我做错了什么?

编辑:也许我应该说,我在一个红帽机器上。

 Scientific Linux SL release 5.4 (Boron) 

如果不是使用守护进程function,而是使用类似于:

 nohup ${exe} >/dev/null 2>&1 & 

在init脚本?

我build议你直接daemonize perl脚本,而不是添加redhat init脚本daemon函数的额外层。 如果你想自己写,就很难得到守护进程。 Proc :: Daemon非常简单。

另外,这里是关于如何编写perl守护进程的讨论。

奖励答案:使用daemontools和Proc :: Daemontools 。 这提供了一个全面的守护进程pipe理系统,您可能已经安装了daemontools。 有些人不喜欢守护神工具,但它完成了工作。

不pipe我写守护程序有多less次,看起来还是很怪异的。 也许我应该只使用守护进程。

如果您正在使用Debian及其衍生产品,请使用带-b选项的start-stop-daemon启动您的进程,而不会出现问题。