启动守护进程的Perl包装器在由cron运行时离开僵尸

时间:2013-11-04 11:50:22

标签: centos bash perl

我有一个Perl脚本来启动进程作为守护进程。但是,当我从cron调用它时,我会离开一个已经不复存在的过程。我把它剥离到一个最小的脚本,我开始'尾'作为守护进程的占位符:

use POSIX "setsid";

$SIG{CHLD} = 'IGNORE';
my $pid = fork();
exit(0) if ($pid > 0);
(setsid() != -1) || die "Can't start a new session: $!";
open (STDIN, '/dev/null') or die ("Cannot read /dev/null: $!\n");
my $logout = "logger -t test";
open (STDOUT, "|$logout")
      or die ("Cannot pipe stdout to $logout: $!\n");
open (STDERR, "|$logout")
      or die ("Cannot pipe stderr to $logout: $!\n");
my $cmd = "tail -f";
exec($cmd);
exit(1);

我用cron运行它并最终得到:

root     18616 18615  0 11:40 ?        00:00:00 [test.pl] <defunct>
root     18617     1  0 11:40 ?        00:00:00 tail -f
root     18618 18617  0 11:40 ?        00:00:00 logger -t test
root     18619 18617  0 11:40 ?        00:00:00 logger -t test

据我所知,它是记录器的管道,它不喜欢,如果我将STDOUT和STDERR发送到/ dev / null,则问题不会发生。

我做错了什么或这是不可能的? (CentOS 5.8)

谢谢,

leonstr

1 个答案:

答案 0 :(得分:1)

这是导致它的管道。来自“Programming Perl”:

(在fork上):

  

如果分叉子项继承了STDIN和STDOUT之类的系统文件描述符   连接到远程管道或插座,您可能必须在孩子中重新打开它们   到/ dev / null。那是因为即使父进程退出,孩子也会活着   使用那些文件句柄的副本。