检查进程是否仍在运行?

为了构build一个穷人的看门狗,并确保应用程序在崩溃的情况下重启(直到我找出原因),我需要编写一个PHP CLI脚本,该脚本将每隔5分钟由cron运行以检查进程仍在运行。

基于这个页面 ,我尝试了下面的代码,但是即使我用伪数据调用它,它总是返回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"; } 

Solutions Collecting From Web of "检查进程是否仍在运行?"

我会使用pgrep来做到这一点(谨慎,未经测试的代码):

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

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

如果你在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看门狗每小时检查一次,看看它是否正在运行(如果不重新启动它)…

你可以试试这个,它结合了这两种方法的一些方面:

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

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

试试这个

“`

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

“`

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

 <?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脚本,exec命令将作为Web服务器用户(www-data)运行; 这个用户看不到其他用户的pid,除非你使用“pidof”

 <?php //########################################## // desc: Diese PHP Script zeig euch ob ein process 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", "process 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

我没有看到这里提到的,但这里有另一种方法,第二个grep出来的等式,我用这个很多我的PHP脚本,应该普遍

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

请享用。

我有一个函数来获得一个进程的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; } 

要检查进程是否按名称运行,可以使用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'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?