如何在init脚本中获取perl守护进程的PID?

时间:2017-02-17 07:52:06

标签: linux perl daemon

我有以下perl脚本:

#!/usr/bin/perl

use strict;
use warnings;
use Proc::Daemon;

Proc::Daemon::Init;

my $continue = 1;
$SIG{TERM} = sub { $continue = 0 };

while ($continue) {
        # stuff
}

我的init脚本中有以下内容:

DAEMON='/path/to/perl/script.pl'
start() {
    PID=`$DAEMON > /dev/null 2>&1 & echo $!`
    echo $PID > /var/run/mem-monitor.pid
}

问题是,这会返回错误的PID!这将返回运行守护程序时启动的父进程的PID,但该进程会立即终止。我需要得到子进程的PID!

3 个答案:

答案 0 :(得分:2)

Proc::Daemon

  

Proc :: Daemon执行以下操作:
  ...
  9.第一个子节点将第二个子节点(守护进程)的PID传输给父节点。此外,如果定义了'pid_file',则可以将守护进程的PID写入文件。然后第一个孩子退出。

然后在new ( %ARGS )

  

pid_file
  定义文件的路径(由父用户拥有),其中将存储守护进程的PID。默认为undef(=不写文件)。

另请参阅Init()方法说明。这一切都意味着您可能希望先使用new

重点是守护进程的是孙子进程。但是,childr会传递pid,并且父级可以使用它。如果在构造函数(守护程序)中设置了pid_file => $file_name,则会将pid写入该文件。

评论要求shell脚本不依赖于另一个脚本编写的文件。

我可以看到两种方法。

  • 从父级打印由$daemon->Init()返回的pid,然后在shell中将其拾取。这被问题中的重定向所击败,但我不知道为什么需要它们。父级和子级在所有设置完成后退出,而守护程序与所有内容分离。

  • Shell脚本可以使用所需的日志文件名作为参数启动Perl脚本,让它通过上述过程将守护进程pid写入该文件。该文件仍由Perl输出,但重要的是由shell脚本决定的。

我想在下面的评论中加入一条声明。我认为这些优于另外两个想到的事情:从shell保存的配置样式文件中选择文件名更复杂,而解析进程表可能不太可靠。

答案 1 :(得分:1)

我以前见过这个,不得不求助于使用STDERR将子PID发送回调用shell脚本。我一直认为这是由于提到退出代码的不可靠性 - 但文档中的细节并不清楚。请尝试这样的事情:

#!/usr/bin/perl
use strict;
use warnings;
use Proc::Daemon;

if( my $pid = Proc::Daemon::Init() ) {
    print STDERR $pid;
    exit;
}

my $continue = 1;
$SIG{TERM} = sub { $continue = 0 };

while ($continue) {
    sleep(20);
    exit;
}

使用这样的调用脚本:

#!/bin/bash
DAEMON='./script.pl'
start() {
    PID=$($DAEMON 2>&1 >/dev/null)
    echo $PID > ./mem-monitor.pid
}
start;

运行bash脚本时,它将捕获STDERR输出(包含正确的PID),并将其存储在文件中。 Perl脚本生成的任何STDOUT都将被发送到/ dev / null - 尽管这不太可能,因为第一级Perl脚本(在这种情况下)很早就退出了。

答案 2 :(得分:0)

感谢zdim和Hakon的建议。它们肯定是可行的,让我走上了正确的轨道,但最终我走了另一条路。我使用$!ps来获取PID,而不是依赖awk,如下所示:

DAEMON='/path/to/perl/script.pl'

start() {
    $DAEMON > /dev/null 2>&1
    PID=`ps aux | grep -v 'grep' | grep "$DAEMON" | awk '{print $2}'`
    echo $PID > /var/run/mem-monitor.pid
}

这可以满足我的强迫症!请注意grep "$DAEMON"中“$ DAEMON”周围的双引号。