我有一个想要守护进程的 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 &
在初始化脚本中?
答案1
我建议你直接将 perl 脚本设为守护进程,而不是添加 redhat init 脚本函数的额外层daemon
。如果你尝试自己编写守护进程,则很难正确设置守护进程。进程::守护进程非常简单。
另外,这里有一个讨论如何编写 perl 守护进程。
奖励答案:使用守护进程工具和Proc::Daemontools。它提供了一个全面的守护进程管理系统,而且您可能已经安装了 daemontools。有些人不喜欢 daemontools,但它确实能完成工作。
无论我写多少次守护进程,它看起来仍然很奇怪。也许我应该只使用守护进程。
答案2
如果您正在使用 Debian 及其衍生产品,请使用start-stop-daemon
-b 选项来顺利启动您的进程。