检查进程是否仍在运行?

Gul*_*har 24 php linux process exec

作为一种构建穷人监视器的方法,并确保应用程序重新启动以防它崩溃(直到我找出原因),我需要编写一个PHP CLI脚本,每隔5mn将由cron运行以检查进程是否正常还在运行

基于此页面,我尝试了以下代码,但即使我用伪造数据调用它也总是返回True:

function processExists($file = false) {
    $exists= false;
    $file= $file ? $file : __FILE__;

    // Check if file is in process list
    exec("ps -C $file -o pid=", $pids);
    if (count($pids) > 1) {
    $exists = true;
    }
    return $exists;
}

#if(processExists("lighttpd"))
if(processExists("dummy"))
    print("Exists\n")
else
    print("Doesn't exist\n");
Run Code Online (Sandbox Code Playgroud)

接下来,我尝试了这段代码 ......

(exec("ps -A | grep -i 'lighttpd -D' | grep -v grep", $output);)
print $output;
Run Code Online (Sandbox Code Playgroud)

......但是没有达到我的期望:

/tmp> ./mycron.phpcli 
Arrayroot:/tmp> 
Run Code Online (Sandbox Code Playgroud)

FWIW,此脚本使用PHP 5.2.5的CLI版本运行,操作系统是uClinux 2.6.19.3.

谢谢你的提示.


编辑:这似乎工作正常

exec("ps aux | grep -i 'lighttpd -D' | grep -v grep", $pids);
if(empty($pids)) {
        print "Lighttpd not running!\n";
} else {
        print "Lighttpd OK\n";
}
Run Code Online (Sandbox Code Playgroud)

irc*_*ell 33

如果你在php中这样做,为什么不使用php代码:

在运行程序中:

define('PIDFILE', '/var/run/myfile.pid');

file_put_contents(PIDFILE, posix_getpid());
function removePidFile() {
    unlink(PIDFILE);
}
register_shutdown_function('removePidFile');   
Run Code Online (Sandbox Code Playgroud)

然后,在监视程序中,您需要做的就是:

function isProcessRunning($pidFile = '/var/run/myfile.pid') {
    if (!file_exists($pidFile) || !is_file($pidFile)) return false;
    $pid = file_get_contents($pidFile);
    return posix_kill($pid, 0);
}
Run Code Online (Sandbox Code Playgroud)

基本上,posix_kill有一个特殊的信号,0实际上不发送信号的过程,但它并检查,看看是否可以发送信号(该过程实际上是运行).

是的,当我需要长时间运行(或至少是可观察的)php进程时,我会经常使用它.通常我会编写初始化脚本来启动PHP程序,然后让cron看门狗每小时检查它是否正在运行(如果没有重启)...


mma*_*tax 21

我习惯pgrep这样做(谨慎,未经测试的代码):


exec("pgrep lighttpd", $pids);
if(empty($pids)) {

    // lighttpd is not running!
}

我有一个类似的东西(但使用SSH隧道)的bash脚本:


#!/bin/sh

MYSQL_TUNNEL="ssh -f -N -L 33060:127.0.0.1:3306 tunnel@db"
RSYNC_TUNNEL="ssh -f -N -L 8730:127.0.0.1:873 tunnel@db"

# MYSQL
if [ -z `pgrep -f -x "$MYSQL_TUNNEL"` ] 
then
    echo Creating tunnel for MySQL.
    $MYSQL_TUNNEL
fi

# RSYNC
if [ -z `pgrep -f -x "$RSYNC_TUNNEL"` ]
then
    echo Creating tunnel for rsync.
    $RSYNC_TUNNEL
fi


您可以使用要监视的命令更改此脚本.

  • 以为我会在这里分享一个快速评论..如图所示,使用`exec`测试`pgrep`,似乎exec的进程将快速创建另一个进程...其中包含相同的字符串.所以它总是返回一个ID ..想想也许使用像`if count = 2`这样的东西...到目前为止使用count = 2的工作......但这里只是一个谨慎的话...... (5认同)

Joh*_*nce 9

你可以尝试这个,它结合了这两种方法的一些方面:

function processExists($processName) {
    $exists= false;
    exec("ps -A | grep -i $processName | grep -v grep", $pids);
    if (count($pids) > 0) {
        $exists = true;
    }
    return $exists;
}
Run Code Online (Sandbox Code Playgroud)

如果这不起作用,您可能只想尝试在系统上运行ps命令并查看它给出的输出.


Ana*_*lev 7

试试这个吧

function processExists ($pid) {
    return file_exists("/proc/{$pid}");
}
Run Code Online (Sandbox Code Playgroud)

函数检查/proc/根目录中是否存在进程文件.仅适用于Linux

  • 需要澄清的是,这只适用于 Linux。不保证其他 UNIX 机器会有 /proc/ 目录 (2认同)