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

Afin de créer un chien de garde et de faire redémarrer une application en cas de panne (jusqu’à ce que je sache pourquoi), je dois écrire un script PHP CLI qui sera exécuté par cron toutes les 5 minutes pour vérifier si le processus est toujours en cours d’exécution.

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

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’obtient 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 indice.


Edit: Cela semble bien fonctionner

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

J’utiliserais pgrep pour faire cela (attention, code non testé):

exec("pgrep lighttpd", $pids); if(empty($pids)) { // lighttpd is not running! }
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
#!/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.

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

Dans le programme en cours d’exécution:

 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, il vous suffit de:

 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 de signal au processus, mais vérifie si un signal peut être envoyé (le processus est en cours d’exécution).

Et oui, je l’utilise assez souvent quand j’ai besoin de longs processus PHP (ou du moins vérifiables). En général, j’écris des scripts d’initialisation pour démarrer le programme PHP, puis j’ai un chien de garde cron pour vérifier toutes les heures pour voir s’il fonctionne (et si ce n’est pas le redémarrer) …

Vous pouvez essayer ceci, qui combine des bits 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, vous pouvez simplement essayer d’exécuter la commande ps sur votre système et voir quelle sortie il donne.

Essaye celui-là

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

La fonction vérifie si le fichier de processus existe dans le /proc/ root. Fonctionne pour Linux uniquement

  

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 des autres utilisateurs, sauf si vous utilisez “pidof”

  1) { echo "$ssortingng: RUNNING
"; } else { echo "$ssortingng: DOWN
"; } } } //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

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 $processSsortingng) { $processArr = explode(' ', sortingm($processSsortingng)); if ( (intval($processArr[0]) != getmypid())&& (strpos($processSsortingng, 'grep '.$processName) === false) ) { $pid = intval($processArr[0]); } } return $pid; } 

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

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

Prendre plaisir.

Pour vérifier si le processus est exécuté par son nom, vous pouvez utiliser pgrep , par exemple

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

ou:

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

selon ce post .

Si vous connaissez le PID du processus, vous pouvez utiliser l’une des fonctions suivantes:

  /** * 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 ssortingng */ public static function getProcessCommand($pid) { $pid = (int) $pid; return sortingm(shell_exec("ps o comm= $pid")); } 

Connexe: Comment vérifier si le PID spécifié est en cours d’exécution sans appeler ps depuis PHP?