web-dev-qa-db-de.com

Überprüfen, ob der Prozess noch läuft?

Um einen Watchdog eines Armen zu erstellen und sicherzustellen, dass eine Anwendung neu gestartet wird, falls sie abstürzt (bis ich weiß, warum), muss ich ein PHP CLI-Skript schreiben, das von cron alle 5mn ausgeführt wird Prüfen Sie, ob der Prozess noch läuft.

Basierend auf dieser Seite habe ich den folgenden Code ausprobiert, der aber immer True zurückgibt, auch wenn ich ihn mit falschen Daten aufrufe:

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

Als nächstes versuchte ich diesen Code ...

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

... aber verstehe nicht was ich erwarte:

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

FWIW, dieses Skript wird mit der CLI-Version von PHP 5.2.5 ausgeführt und das Betriebssystem ist uClinux 2.6.19.3.

Danke für jeden Hinweis.


Edit: Das scheint gut zu funktionieren

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

Ich würde pgrep dazu verwenden (Vorsicht, nicht getesteter Code):


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

    // lighttpd is not running!
}

Ich habe ein Bash-Skript, das etwas ähnliches tut (aber mit SSH-Tunneln):


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

Sie können dieses Skript mit den Befehlen ändern, die Sie überwachen möchten.

20
mmattax

Wenn Sie dies in PHP tun, verwenden Sie den PHP-Code:

Im laufenden Programm:

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

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

Dann müssen Sie im Watchdog-Programm nur noch Folgendes tun:

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

Grundsätzlich hat posix_kill ein spezielles Signal 0, das zwar kein Signal an den Prozess sendet, aber prüft, ob ein Signal gesendet werden kann (der Prozess läuft gerade).

Und ja, ich benutze das oft, wenn ich lange laufende (oder zumindest beobachtbare) PHP-Prozesse brauche. Normalerweise schreibe ich Init-Skripte, um das PHP -Programm zu starten, und dann habe ich einen cron-Watchdog, um stündlich nachzusehen, ob es läuft (und wenn nicht, dann neu starten) ... 

33
ircmaxell

Sie können dies ausprobieren, indem Sie die beiden Ansätze kombinieren:

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

Wenn dies nicht funktioniert, können Sie einfach den Befehl ps auf Ihrem System ausführen und sehen, welche Ausgabe ausgegeben wird.

9
John Lawrence

Probier diese

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

Funktion prüft, ob die Prozessdatei im /proc/-Stammverzeichnis vorhanden ist. Funktioniert nur für Linux

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

?>
1
Softmixt

Ich habe das hier nicht erwähnt, aber hier ist ein anderer Ansatz, der das zweite grep aus der Gleichung herausnimmt. Ich verwende dies mit einer Menge meiner PHP - Skripts und sollte universell funktionieren 

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

Genießen.

1
Destreyf

Das Hauptproblem ist, wenn Sie ein PHP-Skript ausführen, wird der Befehl exec als Benutzer des Webservers (www-data) ausgeführt. Dieser Benutzer kann keine PIDs von anderen Benutzern sehen, es sei denn, Sie verwenden "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");
?>

Weitere Informationen zum Skript hier http://umbru.ch/?p=328

1
Sven Lauber

ich habe eine Funktion, um die PID eines Prozesses zu bekommen ...

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;
}
0
Sergey Eremin