检查进程是否仍在运行?
- 2024-11-08 09:04:00
- admin 原创
- 168
问题描述:
为了构建一个穷人的看门狗并确保应用程序在崩溃时重新启动(直到我弄清楚原因),我需要编写一个 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
")
else
print("Doesn't exist
");
接下来,我尝试了这个代码......
(exec("ps -A | grep -i 'lighttpd -D' | grep -v grep", $output);)
print $output;
...但没有得到我期望的结果:
/tmp> ./mycron.phpcli
Arrayroot:/tmp>
值得一提的是,该脚本使用 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!
";
} else {
print "Lighttpd OK
";
}
解决方案 1:
如果您使用 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 监视程序每小时检查一次以查看它是否正在运行(如果没有运行,则重新启动它)...
解决方案 2:
我会用它pgrep
来做这件事(注意,未经测试的代码):
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
您可以使用想要监控的命令来改变该脚本。
解决方案 3:
您可以尝试一下这种方法,它结合了这两种方法的优点:
function processExists($processName) {
$exists= false;
exec("ps -A | grep -i $processName | grep -v grep", $pids);
if (count($pids) > 0) {
$exists = true;
}
return $exists;
}
如果这不起作用,您可能只想尝试在系统上运行 ps 命令并查看它给出什么输出。
解决方案 4:
尝试这个
function processExists ($pid) {
return file_exists("/proc/{$pid}");
}
函数检查进程文件是否存在于/proc/
根目录中。仅适用于 Linux
解决方案 5:
<?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";
}
?>
解决方案 6:
我没有看到这里提到这一点,但这是另一种方法,将第二个 grep 从等式中取出,我在我的很多 PHP 脚本中都使用了这种方法,应该可以普遍使用
exec("ps aux | grep -i '[l]ighttpd -D'", $pids);
if(empty($pids)) {
print "Lighttpd not running!
";
} else {
print "Lighttpd OK
";
}
享受。
解决方案 7:
主要问题是,如果你运行 php 脚本,exec 命令将以 web 服务器用户 (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
解决方案 8:
我有一个函数可以获取进程的 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;
}
解决方案 9:
要通过名称检查进程是否正在运行,可以使用pgrep
,例如
$is_running = shell_exec("pgrep -f lighttpd");
或者:
exec("pgrep lighttpd", $output, $return);
if ($return == 0) {
echo "Ok, process is running
";
}
按照这篇文章。
如果您知道进程的 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"));
}
相关:如何在不从 PHP 调用 ps 的情况下检查指定的 PID 当前是否正在运行?