作为一种构建穷人监视器的方法,并确保应用程序重新启动以防它崩溃(直到我找出原因),我需要编写一个PHP CLI脚本,每隔5分钟由cron运行一次以检查该过程是否仍在运行。
基于this page,我尝试了以下代码,但即使我用虚假数据调用它也总是返回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");
接下来,我尝试了this code ...
(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";
}
答案 0 :(得分:33)
如果你在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看门狗每小时检查它是否正在运行(如果没有重启)......
答案 1 :(得分:20)
我会使用pgrep
来执行此操作(谨慎,未经测试的代码):
exec("pgrep lighttpd", $pids);
if(empty($pids)) {
// lighttpd is not running!
}
我有一个类似(但使用SSH隧道)的bash脚本:
#!/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
您可以使用要监视的命令更改此脚本。
答案 2 :(得分:9)
你可以尝试这个,它结合了这两种方法中的一些:
function processExists($processName) {
$exists= false;
exec("ps -A | grep -i $processName | grep -v grep", $pids);
if (count($pids) > 0) {
$exists = true;
}
return $exists;
}
如果这不起作用,您可能只想尝试在系统上运行ps命令并查看它给出的输出。
答案 3 :(得分:7)
试试这个
function processExists ($pid) {
return file_exists("/proc/{$pid}");
}
函数检查/proc/
根目录中是否存在进程文件。 仅适用于Linux
答案 4 :(得分:1)
<?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";
}
?>
答案 5 :(得分:1)
我没有在这里看到这一点,但是这里有另一种方法将第二个grep排除在等式之外,我使用了很多我的PHP脚本并且应该普遍使用
exec("ps aux | grep -i '[l]ighttpd -D'", $pids);
if(empty($pids)) {
print "Lighttpd not running!\n";
} else {
print "Lighttpd OK\n";
}
享受。
答案 6 :(得分:1)
主要问题是如果运行php脚本,exec命令将作为web-servers用户运行(www-data);除非您使用“pidof”
,否则此用户无法看到其他用户的pid<?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");
?>
有关此处脚本的更多信息http://umbru.ch/?p=328
答案 7 :(得分:0)
我有一个函数来获取进程的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 :(得分:-1)
要检查进程是否按其名称运行,可以使用pgrep
,例如
$is_running = shell_exec("pgrep -f lighttpd");
或:
exec("pgrep lighttpd", $output, $return);
if ($return == 0) {
echo "Ok, process is running\n";
}
按此post。
如果您知道过程的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"));
}
相关:How to check whether specified PID is currently running without invoking ps from PHP?