我有一个我想要守护的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; }@H_403_4@所以这个脚本基本上每3秒打印一次. @H_403_4@然后,因为我想守护这个脚本,我也把这个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@H_403_4@所以,(如果我已经很好地理解了守护进程的文档),Perl脚本应该在后台运行,如果我执行,输出应该重定向到/ dev / null:
service synpipe_server start@H_403_4@但这是我得到的:
[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]#@H_403_4@所以它启动Perl脚本但运行它而不将它从当前的终端会话中分离出来,我可以看到我的控制台中打印的输出……这实际上并不是我所期待的.此外,PID文件为空(或仅使用换行符,守护程序不返回pid). @H_403_4@有谁知道我做错了什么? @H_403_4@编辑:也许我应该说我在Red Hat机器上.
Scientific Linux SL release 5.4 (Boron)@H_403_4@如果不使用守护进程函数,我会使用类似的东西吗?
nohup ${exe} >/dev/null 2>&1 &@H_403_4@在init脚本中?
解决方法
我建议您直接守护perl脚本,而不是添加redhat init脚本守护程序函数的额外层.如果您尝试自己编写守护进程,很难让守护进程正确.
Proc::Daemon非常简单.
@H_403_4@另外,这是对how to write perl daemons的讨论.
@H_403_4@额外答案:使用daemontools和Proc::Daemontools.这提供了一个全面的守护程序管理系统,您可能已经安装了daemontools.有些人不喜欢daemontools,但它完成了工作.
@H_403_4@无论我写多少次守护进程仍然看起来很怪异.也许我应该使用dæmon.