在Linux中使用PHP检查进程是否正在运行

12

我正在使用kannel通过PHP发送短信。 我想知道如何检查特定的进程是否正在运行。 对于kannel的运行,一个名为bearerbox的进程应该始终在运行。 我想检查这个进程是否正在运行。 因为如果该进程没有运行,则会向我发送邮件通知我。


你可以使用 PHP exec 函数。 - ldg
确保外部用户无法修改您的exec()调用,如果可能,请硬编码它们。糟糕的代码会让心怀恶意的人获得整个系统的访问权限。 - Mattis
@mattis,好的,我会记住的。@ldg,谢谢你的建议伙计,那正是我将要使用的。 - hsinxh
可能是[Checking if process still running?]的重复问题(https://dev59.com/jHA75IYBdhLWcg3wxsJn)。 - kenorb
5个回答

27

最简单的方法是使用pgrep,如果进程存在则退出代码为0,否则为1。

下面是一个例子。

exec("pgrep bearerbox", $output, $return);
if ($return == 0) {
    echo "Ok, process is running\n";
}

你可能需要检查一下,但根据我找到的信息,退出代码是相反的 - 如果存在则为1;如果不存在则为0。有人能澄清一下吗? - Matt Fletcher
@MattFletcher:如果没有找到该名称的进程,pgrep会失败(rc=1)(我刚试过了)。 - Mat
通过 shell 可以实现,但我刚在 PHP CLI 中尝试了一下,它的执行方式正好相反。$output 将返回一个数组,可以为空,也可以包含每个 PID。回显 exec() 命令将返回 PID 或 null。如果进程不存在,则 $return 返回 0,如果存在则返回 1! - Matt Fletcher
这是在Ubuntu 13上使用PHP 5.4.9。 - Matt Fletcher
更新:我想可能是我运行命令的时间有点故障,是我的错...它是描述的原始方式。认为这很奇怪,因为我以前在C中看到过整个“退出代码为0如果存在”的事情 :) - Matt Fletcher
@MattFletcher:很奇怪,我在RedHat上使用的PHP 5.4.8中对于现有进程得到的是$return == 0,否则为1。 - Mat

5
您可以使用exec命令查找您的进程,然后相应地采取行动。
类似于: exec('ps aux | grep bearerbox', $output); 您需要确定服务器返回的内容,以决定它是否正在运行。
祝您好运。

4

有很多方法可以处理这个问题。最简单的方法(也是对您问题的直接回答)是获取“ps”的输出。

守护进程通常会创建一个“pid”文件。该文件包含守护进程的进程ID。如果您的守护进程有该文件,您可以检查文件的内容并查看具有该ID的进程是否仍在运行。这更可靠。

supervisord 也可能具有此功能。最后,也许更好的选择是获得一个真正的监控系统,而不是自己构建一个。Nagios可能是一个不错的选择,但还可能有其他选择。


3

一个简单而实用的PHP监控进程解决方案:PHP-Linux-Process-Monitor

该代码旨在实现以下功能:

$ps = explode("\n", trim(shell_exec('ps axo pid,ppid,%cpu,pmem,user,group,args --sort %cpu')));
foreach($ps AS $process){
$processes[]=preg_split('@\s+@', trim($process), 7 );
}
$head= array_shift($processes);
$processes = array_reverse($processes);
$output='';
foreach ($head AS $f) $output.="<td class=\"head\">$f</td>";
$output=sprintf('<tr class="head">%s</tr>',$output);
foreach($processes AS $p){
    $output.='<tr>';
    foreach ($p AS $i=>$f){
        if($i==0) $output.=sprintf('<td>%1$s</td>',$f);
        elseif($i==2) $output.=sprintf('<td class="cpu">%1$s<ins style="width:%1$s%%"></ins></td>',$f);
        elseif($i==3) $output.=sprintf('<td class="mem">%1$s<ins style="width="%1$s%%"></ins></td>',$f);
        elseif($i == 6) $output.=sprintf('<td class="command">%1$s</td>',$f);
        else $output.=sprintf('<td>%1$s</td>',$f);
    }
    $output.='</tr>';
}
$cpu=implode('&nbsp;&nbsp;&nbsp;', sys_getloadavg());
$output=sprintf('<table data-cpu="%s" id="process">%s</table>',$cpu, $output);

0

这是最好的方式

<?php
exec("ps -eo comm,pid | awk '$1 == "."\"gs\""." { print $2 }'", $output);
if ($output != 0) {
    echo "The process gs is running\n";
}
?>

在上面的代码中,gs是我正在检查的进程。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接