正在检查进程是否仍在运行?

2022-08-30 14:06:41

作为构建穷人的看门狗并确保应用程序在崩溃时重新启动的一种方式(直到我弄清楚原因),我需要编写一个PHP CLI脚本,该脚本将由cron每500万运行一次,以检查该进程是否仍在运行。

基于此页面,我尝试了以下代码,但即使我用虚假数据调用它,它也总是返回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");

接下来,我尝试了此代码...

(exec("ps -A | grep -i 'lighttpd -D' | grep -v grep", $output);)
print $output;

...但不要得到我所期望的:

/tmp> ./mycron.phpcli 
Arrayroot:/tmp> 

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";
}

答案 1

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

在正在运行的程序中:

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

file_put_contents(PIDFILE, posix_getpid());
function removePidFile() {
    unlink(PIDFILE);
}
register_shutdown_function('removePidFile');   

然后,在看门狗程序中,您需要做的就是:

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);
}

基本上,posix_kill有一个特殊的信号,实际上并没有向进程发送信号,但它确实检查是否可以发送信号(进程实际上正在运行)。0

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


答案 2

我会用它来做这件事(注意,未经测试的代码):pgrep


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

    // lighttpd is not running!
}

我有一个bash脚本,可以做类似的事情(但使用SSH隧道):


#!/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


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


推荐