我有一些像这样的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?
答案 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;
让所有实例都运行到数组中,然后用它做你想做的事。