Подтвердить что ты не робот

Проверка работоспособности процесса?

Как способ создания сторожевого пса-бедняка и убедитесь, что приложение перезагрузилось, если оно сработает (пока не выясню, почему), мне нужно написать PHP CLI script, который будет выполняться cron каждые 5mn чтобы проверить, все еще запущен процесс.

Основываясь на на этой странице, я попробовал следующий код, но он всегда возвращает 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, этот script запускается с версией CLI для PHP 5.2.5, а ОС - 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";
}
4b9b3361

Ответ 1

Я бы использовал pgrep для этого (осторожный, непроверенный код):


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

    // lighttpd is not running!
}

У меня есть bash script, который делает что-то подобное (но с туннелями SSH):


#!/bin/sh

MYSQL_TUNNEL="ssh -f -N -L 33060:127.0.0.1:3306 [email protected]"
RSYNC_TUNNEL="ssh -f -N -L 8730:127.0.0.1:873 [email protected]"

# 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


Вы можете изменить этот script с помощью команд, которые вы хотите контролировать.

Ответ 2

Если вы делаете это в 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, чтобы проверить, работает ли она (и если не перезапустить ее)...

Ответ 3

Вы можете попробовать это, которое объединяет бит этих двух подходов:

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

Если это не сработает, вы можете просто попробовать запустить команду ps в своей системе и посмотреть, какой результат она дает.

Ответ 4

Попробуйте этот

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

Функция проверяет, существует ли файл процесса в корневом каталоге /proc/. Работает только для Linux

Ответ 5

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

?>

Ответ 6

Основная проблема заключается в том, что если вы запустите php script, команда exec будет запущена как пользователь веб-серверов (www-data); этот пользователь не может видеть pid от других пользователей, если вы не используете "pidof"

<?php
//##########################################
// desc: Diese PHP скрипт 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");
?>

Подробнее о script здесь http://umbru.ch/?p=328

Ответ 7

У меня есть функция для получения 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;
}

Ответ 8

Я не видел этого здесь, но здесь другой подход, взявший второй grep из уравнения, я использую это со многими моими PHP-скриптами и должен работать повсеместно

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

Enjoy.

Ответ 9

Чтобы проверить, запущен ли процесс по имени, вы можете использовать pgrep, например

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

или

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

в соответствии с этим сообщением.

Если вы знаете 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 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, не вызывая ps из PHP?