perl pgrep返回多个pids

时间:2015-08-01 01:27:18

标签: perl

我有一些像这样的perl代码来获取进程的pid 存在。我想知道pgrep的返回状态,这样我就可以知道pid是否有效。这是代码:

#!/usr/bin/perl -w
my $pid=`pgrep -n -f \"akonadiserver\"`;
print "$? ";
chomp $pid;
print "Output1: $pid\n";
$pid=`pgrep -n -f \"akonadiserver\"`;
my $evalue=${^CHILD_ERROR_NATIVE};
chomp $pid;
print "Output2: $pid, $evalue\n";

但每当我运行它时,我会得到以下结果:

0 Output1: 3054
Output2: 3056, 0

另一次运行

0 Output1: 3059
Output2: 3061, 0

但在系统中:

$ pgrep -n -f akonadiserver
1862

这里看到的几个问题:

1)返回的pid一直在变化,很可能是匹配的 grep进程本身。

2)我没有办法找到退回的pid是否有效。 $? 没有帮助。

如何检查返回状态以及如何在perl中正确使用pgrep?

2 个答案:

答案 0 :(得分:2)

从Perl脚本运行`pgrep -n -f akonadiserver`相当于从终端运行sh -c "pgrep -n -f akonadiserver"

来自perlop

  

<强> QX / STRING /
  一个字符串,可以(可能)插入,然后作为系统命令用/ bin / sh或其等价物执行。

问题是使用-f选项和pgrep将匹配用于调用进程的完整命令行。这还包括当前的pgrep命令,因为它的命令行看起来像sh -c "pgrep -n -f akonadiserver",它将与字符串"akonadiserver"匹配。由于您还将-n标记与pgrep一起使用,因此它只会返回与"akonadiserver"匹配的最新进程,而这很可能是pgrep命令本身({{1} })..这就解释了为什么你得到错误的进程ID。

但是它没有解释为什么它仍然可以在终端窗口中运行。原因是在终端窗口中,sh -c "pgrep -n -f akonadiserver"命令与pgrep而不是bash一起运行(从Perl脚本开始),请参阅此问题以获取有关差异的更多信息:{ {3}}。因此,从终端窗口运行sh将不包含pgrep -f命令本身,因此它将适用于您的情况。

要从Perl获得可靠的结果,您应该使用Difference between pgrep in sh and bash

pgrep

答案 1 :(得分:0)

在我看来,pgrep返回由您正在寻找的进程启动的最新(-n)子进程的pid,至少在我的系统上会发生这种情况。

我一直用ps来做这些事情,怎么样:

my $pid = (split(" ",`ps -A | grep \"akonadiserver\"`))[0];

代替,或

my @pids = map{ $_ =~ /(\d+)/; $1 }split("\n", `ps -A | grep \"akonadiserver\"` );
print "mutiple instances: @pids\n" if @pids > 1;
print "pid: ".$pids[0]."\n" if @pids == 1;

让所有实例都运行到数组中,然后用它做你想做的事。