检查进程是否仍在运行?

发布于 2024-09-07 01:45:49 字数 1282 浏览 4 评论 0原文

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

基于此页面,我尝试了以下代码,但它总是返回 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";
}

As a way to build a poor-man's watchdog and make sure an application is restarted in case it crashes (until I figure out why), I need to write a PHP CLI script that will be run by cron every 5mn to check whether the process is still running.

Based on this page, I tried the following code, but it always returns True even if I call it with bogus data:

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

Next, I tried this code...

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

... but don't get what I expect:

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

FWIW, this script is run with the CLI version of PHP 5.2.5, and the OS is uClinux 2.6.19.3.

Thank you for any hint.


Edit: This seems to work fine

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

尤怨 2024-09-14 01:45:49

如果您在 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 进程时,我确实经常使用它。通常,我编写 init 脚本来启动 PHP 程序,然后使用 cron 看门狗每小时检查它是否正在运行(如果没有重新启动它)...

If you're doing it in php, why not use php code:

In the running program:

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

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

Then, in the watchdog program, all you need to do is:

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

Basically, posix_kill has a special signal 0 that doesn't actually send a signal to the process, but it does check to see if a signal can be sent (the process is actually running).

And yes, I do use this quite often when I need long running (or at least watchable) php processes. Typically I write init scripts to start the PHP program, and then have a cron watchdog to check hourly to see if it's running (and if not restart it)...

慈悲佛祖 2024-09-14 01:45:49

我会使用 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


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

I'd use pgrep to do this (caution, untested code):


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

    // lighttpd is not running!
}

I have a bash script that does something similar (but with SSH tunnels):


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


You could alter this script with the commands that you want to monitor.

知你几分 2024-09-14 01:45:49

您可以尝试这个,它结合了这两种方法的一些部分:

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

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

You can try this, which combines bits of those two approaches:

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

If that doesn't work, you may want to just try running the ps command on your system and seeing what output it gives.

喵星人汪星人 2024-09-14 01:45:49

试试这个

function processExists ($pid) {
    return file_exists("/proc/{$pid}");
}

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

Try this one

function processExists ($pid) {
    return file_exists("/proc/{$pid}");
}

Function checks whether process file is exists in /proc/ root directory. Works for Linux only

素衣风尘叹 2024-09-14 01:45:49
<?php

function check_if_process_is_running($process)
{
    exec("/bin/pidof $process",$response);
    if ($response)
    {
         return true;
    } else
    {
         return false;
    }
}

if (check_if_process_is_running("mysqld"))
{
      echo "MySQL is running";
} else
{
      echo "Mysql stopped";
}

?>
<?php

function check_if_process_is_running($process)
{
    exec("/bin/pidof $process",$response);
    if ($response)
    {
         return true;
    } else
    {
         return false;
    }
}

if (check_if_process_is_running("mysqld"))
{
      echo "MySQL is running";
} else
{
      echo "Mysql stopped";
}

?>
ˇ宁静的妩媚 2024-09-14 01:45:49

我没有看到这里提到这一点,但这里有另一种方法,将第二个 grep 排除在等式之外,我在很多 PHP 脚本中使用它,并且应该普遍适用

exec("ps aux | grep -i '[l]ighttpd -D'", $pids);
if(empty($pids)) {
        print "Lighttpd not running!\n";
} else {
        print "Lighttpd OK\n";
}

I didn't see this mentioned here, but here's another approach taking the second grep out of the equation, i use this with alot of my PHP scripts and should work universally

exec("ps aux | grep -i '[l]ighttpd -D'", $pids);
if(empty($pids)) {
        print "Lighttpd not running!\n";
} else {
        print "Lighttpd OK\n";
}

Enjoy.

甜味超标? 2024-09-14 01:45:49

主要问题是,如果您运行 php 脚本,exec 命令将以 Web 服务器用户 (www-data) 身份运行;该用户无法看到其他用户的 pid,除非您使用“pidof”

<?php
//##########################################
// desc: Diese PHP Script zeig euch ob ein Prozess läuft oder nicht
// autor: seevenup
// version: 1.3
// info: Da das exec kommando als apache user (www-data) ausgefuert
//       wird, muss pidof benutzt werden da es prozesse von
//       anderen usern anzeigen kann
//##########################################

if (!function_exists('server_status')) {
        function server_status($string,$name) {
                $pid=exec("pidof $name");
                exec("ps -p $pid", $output);

                if (count($output) > 1) {
                        echo "$string: <font color='green'><b>RUNNING</b></font><br>";
                }
                else {
                        echo "$string: <font color='red'><b>DOWN</b></font><br>";
                }
        }
}

//Beispiel "Text zum anzeigen", "Prozess Name auf dem Server"
server_status("Running With Rifles","rwr_server");
server_status("Starbound","starbound_server");
server_status("Minecraft","minecarf");
?>

有关该脚本的更多信息,请参见此处 http: //umbru.ch/?p=328

The main problem is the if you run a php script, the exec command will be run as the web-servers user (www-data); this user can't see pid's from other users, unless you use "pidof"

<?php
//##########################################
// desc: Diese PHP Script zeig euch ob ein Prozess läuft oder nicht
// autor: seevenup
// version: 1.3
// info: Da das exec kommando als apache user (www-data) ausgefuert
//       wird, muss pidof benutzt werden da es prozesse von
//       anderen usern anzeigen kann
//##########################################

if (!function_exists('server_status')) {
        function server_status($string,$name) {
                $pid=exec("pidof $name");
                exec("ps -p $pid", $output);

                if (count($output) > 1) {
                        echo "$string: <font color='green'><b>RUNNING</b></font><br>";
                }
                else {
                        echo "$string: <font color='red'><b>DOWN</b></font><br>";
                }
        }
}

//Beispiel "Text zum anzeigen", "Prozess Name auf dem Server"
server_status("Running With Rifles","rwr_server");
server_status("Starbound","starbound_server");
server_status("Minecraft","minecarf");
?>

More information about the script here http://umbru.ch/?p=328

尛丟丟 2024-09-14 01:45:49

我有一个函数可以获取进程的pid...

function getRunningPid($processName) {
    $pid = 0;
    $processes = array();
    $command = 'ps ax | grep '.$processName;
    exec($command, $processes);
    foreach ($processes as $processString) {
        $processArr = explode(' ', trim($processString));
            if (
            (intval($processArr[0]) != getmypid())&&
            (strpos($processString, 'grep '.$processName) === false)
        ) {
            $pid = intval($processArr[0]);
        }
    }
    return $pid;
}

i have a function to get the pid of a process...

function getRunningPid($processName) {
    $pid = 0;
    $processes = array();
    $command = 'ps ax | grep '.$processName;
    exec($command, $processes);
    foreach ($processes as $processString) {
        $processArr = explode(' ', trim($processString));
            if (
            (intval($processArr[0]) != getmypid())&&
            (strpos($processString, 'grep '.$processName) === false)
        ) {
            $pid = intval($processArr[0]);
        }
    }
    return $pid;
}
够运 2024-09-14 01:45:49

要检查进程是否正在按其名称运行,您可以使用 pgrep,例如

$is_running = shell_exec("pgrep -f lighttpd");

或:

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

按照此 post< /a>.

如果您知道进程的PID,则可以使用以下函数之一:

  /**
   * Checks whether the process is running.
   *
   * @param int $pid Process PID.
   * @return bool
   */
  public static function isProcessRunning($pid) {
    // Calling with 0 kill signal will return true if process is running.
    return posix_kill((int) $pid, 0);
  }

  /**
   * Get the command of the process.
   * For example apache2 in case that's the Apache process.
   *
   * @param int $pid Process PID.
   * @return string
   */
  public static function getProcessCommand($pid) {
    $pid = (int) $pid;
    return trim(shell_exec("ps o comm= $pid"));
  }

相关:如何在不调用的情况下检查指定的PID当前是否正在运行PHP 中的 ps?

To check whether process is running by its name, you can use pgrep, e.g.

$is_running = shell_exec("pgrep -f lighttpd");

or:

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

as per this post.

If you know the PID of the process, you can use one the following functions:

  /**
   * Checks whether the process is running.
   *
   * @param int $pid Process PID.
   * @return bool
   */
  public static function isProcessRunning($pid) {
    // Calling with 0 kill signal will return true if process is running.
    return posix_kill((int) $pid, 0);
  }

  /**
   * Get the command of the process.
   * For example apache2 in case that's the Apache process.
   *
   * @param int $pid Process PID.
   * @return string
   */
  public static function getProcessCommand($pid) {
    $pid = (int) $pid;
    return trim(shell_exec("ps o comm= $pid"));
  }

Related: How to check whether specified PID is currently running without invoking ps from PHP?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文