[英]How to get PID of perl daemon in init script?
我有以下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
}
我的初始化脚本中包含以下内容:
DAEMON='/path/to/perl/script.pl'
start() {
PID=`$DAEMON > /dev/null 2>&1 & echo $!`
echo $PID > /var/run/mem-monitor.pid
}
问题是,这将返回错误的PID! 这将返回运行守护程序时启动的父进程的PID,但是该进程将立即终止。 我需要获取子进程的PID!
Proc :: Daemon执行以下操作:
...
9.第一个孩子将第二个孩子(守护程序)的PID传输给父对象。 此外,如果定义了“ pid_file”,则可以将守护进程的PID写入文件。 然后第一个孩子退出。
然后在new ( %ARGS )
pid_file
定义将存储守护进程的PID的文件(由父用户拥有)的路径。 默认为undef(=不写文件)。
另请Init()
方法说明。 这一切都意味着您可能要先使用new
。
关键是,子进程才是守护进程。 但是,子级将pid传递给它,并且父级可以使用它。 如果在构造函数(守护程序)中设置了pid_file => $file_name
,则将pid写入该文件。
注释要求外壳程序脚本不依赖于另一个脚本编写的文件。
我可以看到两种方法。
从父级打印由$daemon->Init()
返回的pid,并在shell中进行拾取。 这个问题在重定向中被打败了,但是我不知道为什么需要它们。 设置完所有设置后,父级和子级直接退出,而守护程序则与所有内容分离。
Shell脚本可以使用所需的日志文件名作为参数来启动Perl脚本,从而通过上述过程将守护进程pid写入该文件。 该文件仍由Perl输出,但是有关它的重要事项由Shell脚本决定。
我想在下面的评论中发表声明。 我认为这些要比其他两件事优越:从外壳程序保留的配置样式文件中选择文件名更加复杂,而解析进程表可能不可靠。
我之前已经看过这一点,不得不使用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脚本确实(在这种情况下)很早就退出了。
感谢zdim和Hakon的建议。 他们当然是可行的,并且使我走上了正确的道路,但最终我走了一条不同的路。 而不是依靠$!
,我使用ps
和awk
来获取PID,如下所示:
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"
周围的双引号。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.