web-dev-qa-db-fra.com

Vérifier si le processus est toujours en cours d'exécution?

Pour construire un chien de garde des pauvres et s’assurer que l’application est redémarrée au cas où elle se bloquerait (jusqu’à ce que je sache pourquoi), j’ai besoin d’écrire un script CLI PHP qui sera exécuté par cron toutes les 5 minutes. vérifiez si le processus est toujours en cours d'exécution.

Sur la base de cette page , j’ai essayé le code suivant, mais il renvoie toujours True même si je l’appelle avec de fausses données:

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

Ensuite, j'ai essayé ce code ...

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

... mais n'obtenez pas ce que j'attends:

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

FWIW, ce script est exécuté avec la version CLI de PHP 5.2.5 et le système d'exploitation est uClinux 2.6.19.3.

Merci pour tout conseil.


Edit: Cela semble fonctionner correctement

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

J'utiliserais pgrep pour faire ceci (attention, code non testé):


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

    // lighttpd is not running!
}

J'ai un script bash qui fait quelque chose de similaire (mais avec des tunnels 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

Vous pouvez modifier ce script avec les commandes que vous souhaitez surveiller.

20
mmattax

Si vous le faites en php, pourquoi ne pas utiliser le code php:

Dans le programme en cours:

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

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

Ensuite, dans le programme de surveillance, tout ce que vous devez faire est:

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

Fondamentalement, posix_kill a un signal spécial 0 qui n'envoie pas réellement de signal au processus, mais il vérifie si un signal peut être envoyé (le processus est en cours d'exécution).

Et oui, je l’utilise assez souvent lorsque j’ai besoin de processus php longs (ou au moins accessibles). En général, j'écris des scripts d'initialisation pour démarrer le programme PHP, puis je dispose d'un chien de garde cron pour vérifier toutes les heures s'il est exécuté (et si ce n'est pas le redémarrer) ... 

33
ircmaxell

Vous pouvez essayer ceci, qui combine des morceaux de ces deux approches:

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

Si cela ne fonctionne pas, essayez d’exécuter la commande ps sur votre système et de voir la sortie qu’elle donne.

9
John Lawrence

Essaye celui-là

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

La fonction vérifie si le fichier de processus existe dans le répertoire racine /proc/. Fonctionne uniquement sous 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

Je n'ai pas vu cela mentionné ici, mais voici une autre approche prenant le second grep de l'équation, je l'utilise avec beaucoup de mes scripts PHP et devrait fonctionner universellement 

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

Prendre plaisir.

1
Destreyf

Le problème principal est que si vous exécutez un script php, la commande exec sera exécutée en tant qu'utilisateur du serveur Web (www-data); cet utilisateur ne peut pas voir les pid d'autres utilisateurs, sauf si vous utilisez "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");
?>

Plus d'informations sur le script ici http://umbru.ch/?p=328

1
Sven Lauber

j'ai une fonction pour obtenir le pid d'un processus ...

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