如何检查php脚本是否仍在运行

时间:2021-01-19 00:07:29

I have a PHP script that listens on a queue. Theoretically, it's never supposed to die. Is there something to check if it's still running? Something like Ruby's God ( http://god.rubyforge.org/ ) for PHP?

我有一个PHP脚本监听队列。理论上说,它永远不会死。有什么东西可以检查它是否还在运行吗?比如Ruby的上帝(http://god.rubyforge.org/) ?

God is language agnostic but it would be nice to have a solution that works on windows as well.

上帝是语言的不可知论者,但是如果有一个同样适用于windows的解决方案就好了。

12 个解决方案

#1


12  

I had the same issue - wanting to check if a script is running. So I came up with this and I run it as a cron job. It grabs the running processes as an array and cycles though each line and checks for the file name. Seems to work fine. Replace #user# with your script user.

我有同样的问题——想检查脚本是否在运行。所以我想到了这个,并把它作为一个cron job运行。它以数组的形式获取正在运行的进程,并循环遍历每一行并检查文件名。似乎工作好。用您的脚本用户替换#用户#。

exec("ps -U #user# -u #user# u", $output, $result);
foreach ($output AS $line) if(strpos($line, "test.php")) echo "found";

#2


4  

Just append a second command after the script. When/if it stops, the second command is invoked. Eg.:

只需在脚本后面添加第二个命令。当/如果停止,将调用第二个命令。如:

php daemon.php 2>&1 | mail -s "Daemon stopped" you@example.org

Edit:

Technically, this invokes the mailer right away, but only completes the command when the php script ends. Doing this captures the output of the php-script and includes in the mail body, which can be useful for debugging what caused the script to halt.

从技术上讲,这将立即调用mailer,但只在php脚本结束时完成该命令。这样做可以捕获php脚本的输出并包含在邮件主体中,这对于调试导致脚本停止的原因非常有用。

#3


4  

In linux run ps as follows:

在linux中运行ps如下:

ps -C php -f

You could then do in a php script:

然后,您可以使用php脚本:

$output = shell_exec('ps -C php -f');
if (strpos($output, "php my_script.php")===false) { 
  shell_exec('php my_script.php  > /dev/null 2>&1 &');
}

The above code lists all php processes running in full, then checks to see if "my_script.php" is in the list of running processes, if not it runs the process and does not wait for the process to terminate to carry on doing what it was doing.

上面的代码列出了所有正在运行的php进程,然后检查是否“my_script”。php“在正在运行的进程列表中,如果没有,它将运行进程,并且不会等待进程终止来执行它正在执行的操作。

#4


2  

Simple bash script

简单的bash脚本

#!/bin/bash
while [true]; do
    if ! pidof -x script.php;
    then
        php script.php &
    fi
done

#5


2  

Not for windows, but...

没有窗户,但是……

I've got a couple of long-running PHP scripts, that have a shell script wrapping it. You can optionally return a value from the script that will be checked in the shell-script to exit, restart immediately, or sleep for a few seconds -and then restart.

我有几个长期运行的PHP脚本,有一个shell脚本对其进行包装。您可以选择从shell脚本中检查的脚本返回一个值,以退出、立即重新启动或休眠几秒钟,然后重新启动。

Here's a simple one that just keeps running the PHP script till it's manually stopped.

这里有一个简单的例子,它一直运行PHP脚本,直到手动停止。

#!/bin/bash
clear
date
php -f cli-SCRIPT.php
echo "wait a little while ..."; sleep 10
exec $0

The "exec $0" restarts the script, without creating a sub-process that will have to unravel later (and take up resources in the meantime). This bash script wraps a mail-sender, so it's not a problem if it exits and pauses for a moment.

“exec $0”重新启动脚本,而不需要创建一个稍后会被分解的子进程(同时占用资源)。这个bash脚本封装了一个邮件发送方,所以如果它退出并暂停片刻,就不是问题。

#6


0  

One possible solution is to have it listen on a port using the socket functions. You can check that the socket is still listening with a simple script. Even a monitoring service like pingdom could monitor its status. If it dies, the socket is no longer listening.

一种可能的解决方案是让它使用套接字函数监听端口。您可以使用一个简单的脚本检查套接字是否仍在监听。甚至像pingdom这样的监视服务也可以监视它的状态。如果它死了,插座就不再听了。

Plenty of solutions.. Good luck.

大量的解决方案。祝你好运。

#7


0  

If you have your hands on the script, you can just ask him to set a time value every X times in db, and then let a cron job check if that value is up to date.

如果您熟悉这个脚本,您可以要求他在db中每X次设置一个时间值,然后让cron job检查该值是否最新。

#8


0  

troelskn wrote:

troelskn写道:

Just append a second command after the script. When/if it stops, the second command is invoked. Eg.:

只需在脚本后面添加第二个命令。当/如果停止,将调用第二个命令。如:

php daemon.php | mail -s "Daemon stopped" you@example.org

This will call mail each time a line is printed in daemon.php (which should be never, but still.)

这将在每次在守护进程中打印一行时调用mail。php(应该永远不会,但仍然会)

Instead, use the double ampersand operator to separate the commands, i.e.

相反,使用双&符操作符来分离命令,例如。

php daemon.php & mail -s "Daemon stopped" you@example.org

#9


0  

You can write in your crontab something like this:

你可以在crontab中这样写:

0 3 * * * /usr/bin/php -f /home/test/test.php my_special_cron

Your test.php file should look like this:

你的测试。php文件应该如下所示:

<?php

php_sapi_name() == 'cli' || exit;

if($argv[1]) {
   substr_count(shell_exec('ps -ax'), $argv[1]) < 3 || exit;
}

// your code here

That way you will have only one active instace of the cron job with my-special-cron as process key. So you can add more jobs within the same php file.

这样,您将只有一个活动的cron作业的instace,并使用my-special-cron作为进程键。因此,您可以在同一个php文件中添加更多的作业。

test.php system_send_emails sendEmails

测试。php system_send_emails sendEmails

test.php system_create_orders orderExport

测试。php system_create_orders orderExport

#10


0  

Inspired from Justin Levene's answer and improved it as ps -C doesn't work in Mac, which I need in my case. So you can use this in a php script (maybe just before you need daemon alive), tested in both Mac OS X 10.11.4 & Ubuntu 14.04:

从Justin Levene的答案中得到启发,并将其改进为ps -C在Mac上不起作用,这是我需要的。所以你可以在一个php脚本中使用它(可能就在你需要守护程序之前),在Mac OS X 10.11.4和Ubuntu 14.04中测试:

$daemonPath = "FULL_PATH_TO_DAEMON";
$runningPhpProcessesOfDaemon = (int) shell_exec("ps aux | grep -c '[p]hp ".$daemonPath."'");
if ($runningPhpProcessesOfDaemon === 0) {
    shell_exec('php ' . $daemonPath . ' > /dev/null 2>&1 &');
}

Small but useful detail: Why grep -c '[p]hp ...' instead of grep -c 'php ...'?

小而有用的细节:为什么grep -c ' hp…而不是grep -c 'php…?

Because while counting processes grep -c 'php ...' will be counted as a process that fits in our pattern. So using a regex for first letter of php makes our command different from pattern we search.

因为当计算grep -c 'php进程时…将被视为符合我们模式的过程。因此,对于php的第一个字母使用regex将使我们的命令与我们搜索的模式不同。

#11


0  

If you're having trouble checking for the PHP script directly, you can make a trivial wrapper and check for that. I'm not sufficiently familiar with Windows scripting to put how it's done here, but in Bash, it'd look like...

如果您在直接检查PHP脚本时遇到了麻烦,您可以做一个简单的包装并检查它。我不太熟悉Windows脚本编程,无法在这里说明它是如何实现的,但是在Bash中,它看起来像是……

wrapper_for_test_php.sh

wrapper_for_test_php.sh

#!/bin/bash
php test.php

Then you'd just check for the wrapper like you'd check for any other bash script: pidof -x wrapper_for_test_php.sh

然后,您只需检查包装器,就像检查任何其他bash脚本一样:pidof -x wrapper_for_test_php.sh

#12


0  

I have used cmder for windows and based on this script I came up with this one that I managed to deploy on linux later.

我在windows中使用了cmder,基于这个脚本,我开发出了这个我后来在linux上部署的脚本。

#!/bin/bash
 clear
 date
 while true
 do
    php -f processEmails.php
    echo "wait a little while for 5 secobds..."; 
    sleep 5
 done 

#1


12  

I had the same issue - wanting to check if a script is running. So I came up with this and I run it as a cron job. It grabs the running processes as an array and cycles though each line and checks for the file name. Seems to work fine. Replace #user# with your script user.

我有同样的问题——想检查脚本是否在运行。所以我想到了这个,并把它作为一个cron job运行。它以数组的形式获取正在运行的进程,并循环遍历每一行并检查文件名。似乎工作好。用您的脚本用户替换#用户#。

exec("ps -U #user# -u #user# u", $output, $result);
foreach ($output AS $line) if(strpos($line, "test.php")) echo "found";

#2


4  

Just append a second command after the script. When/if it stops, the second command is invoked. Eg.:

只需在脚本后面添加第二个命令。当/如果停止,将调用第二个命令。如:

php daemon.php 2>&1 | mail -s "Daemon stopped" you@example.org

Edit:

Technically, this invokes the mailer right away, but only completes the command when the php script ends. Doing this captures the output of the php-script and includes in the mail body, which can be useful for debugging what caused the script to halt.

从技术上讲,这将立即调用mailer,但只在php脚本结束时完成该命令。这样做可以捕获php脚本的输出并包含在邮件主体中,这对于调试导致脚本停止的原因非常有用。

#3


4  

In linux run ps as follows:

在linux中运行ps如下:

ps -C php -f

You could then do in a php script:

然后,您可以使用php脚本:

$output = shell_exec('ps -C php -f');
if (strpos($output, "php my_script.php")===false) { 
  shell_exec('php my_script.php  > /dev/null 2>&1 &');
}

The above code lists all php processes running in full, then checks to see if "my_script.php" is in the list of running processes, if not it runs the process and does not wait for the process to terminate to carry on doing what it was doing.

上面的代码列出了所有正在运行的php进程,然后检查是否“my_script”。php“在正在运行的进程列表中,如果没有,它将运行进程,并且不会等待进程终止来执行它正在执行的操作。

#4


2  

Simple bash script

简单的bash脚本

#!/bin/bash
while [true]; do
    if ! pidof -x script.php;
    then
        php script.php &
    fi
done

#5


2  

Not for windows, but...

没有窗户,但是……

I've got a couple of long-running PHP scripts, that have a shell script wrapping it. You can optionally return a value from the script that will be checked in the shell-script to exit, restart immediately, or sleep for a few seconds -and then restart.

我有几个长期运行的PHP脚本,有一个shell脚本对其进行包装。您可以选择从shell脚本中检查的脚本返回一个值,以退出、立即重新启动或休眠几秒钟,然后重新启动。

Here's a simple one that just keeps running the PHP script till it's manually stopped.

这里有一个简单的例子,它一直运行PHP脚本,直到手动停止。

#!/bin/bash
clear
date
php -f cli-SCRIPT.php
echo "wait a little while ..."; sleep 10
exec $0

The "exec $0" restarts the script, without creating a sub-process that will have to unravel later (and take up resources in the meantime). This bash script wraps a mail-sender, so it's not a problem if it exits and pauses for a moment.

“exec $0”重新启动脚本,而不需要创建一个稍后会被分解的子进程(同时占用资源)。这个bash脚本封装了一个邮件发送方,所以如果它退出并暂停片刻,就不是问题。

#6


0  

One possible solution is to have it listen on a port using the socket functions. You can check that the socket is still listening with a simple script. Even a monitoring service like pingdom could monitor its status. If it dies, the socket is no longer listening.

一种可能的解决方案是让它使用套接字函数监听端口。您可以使用一个简单的脚本检查套接字是否仍在监听。甚至像pingdom这样的监视服务也可以监视它的状态。如果它死了,插座就不再听了。

Plenty of solutions.. Good luck.

大量的解决方案。祝你好运。

#7


0  

If you have your hands on the script, you can just ask him to set a time value every X times in db, and then let a cron job check if that value is up to date.

如果您熟悉这个脚本,您可以要求他在db中每X次设置一个时间值,然后让cron job检查该值是否最新。

#8


0  

troelskn wrote:

troelskn写道:

Just append a second command after the script. When/if it stops, the second command is invoked. Eg.:

只需在脚本后面添加第二个命令。当/如果停止,将调用第二个命令。如:

php daemon.php | mail -s "Daemon stopped" you@example.org

This will call mail each time a line is printed in daemon.php (which should be never, but still.)

这将在每次在守护进程中打印一行时调用mail。php(应该永远不会,但仍然会)

Instead, use the double ampersand operator to separate the commands, i.e.

相反,使用双&符操作符来分离命令,例如。

php daemon.php & mail -s "Daemon stopped" you@example.org

#9


0  

You can write in your crontab something like this:

你可以在crontab中这样写:

0 3 * * * /usr/bin/php -f /home/test/test.php my_special_cron

Your test.php file should look like this:

你的测试。php文件应该如下所示:

<?php

php_sapi_name() == 'cli' || exit;

if($argv[1]) {
   substr_count(shell_exec('ps -ax'), $argv[1]) < 3 || exit;
}

// your code here

That way you will have only one active instace of the cron job with my-special-cron as process key. So you can add more jobs within the same php file.

这样,您将只有一个活动的cron作业的instace,并使用my-special-cron作为进程键。因此,您可以在同一个php文件中添加更多的作业。

test.php system_send_emails sendEmails

测试。php system_send_emails sendEmails

test.php system_create_orders orderExport

测试。php system_create_orders orderExport

#10


0  

Inspired from Justin Levene's answer and improved it as ps -C doesn't work in Mac, which I need in my case. So you can use this in a php script (maybe just before you need daemon alive), tested in both Mac OS X 10.11.4 & Ubuntu 14.04:

从Justin Levene的答案中得到启发,并将其改进为ps -C在Mac上不起作用,这是我需要的。所以你可以在一个php脚本中使用它(可能就在你需要守护程序之前),在Mac OS X 10.11.4和Ubuntu 14.04中测试:

$daemonPath = "FULL_PATH_TO_DAEMON";
$runningPhpProcessesOfDaemon = (int) shell_exec("ps aux | grep -c '[p]hp ".$daemonPath."'");
if ($runningPhpProcessesOfDaemon === 0) {
    shell_exec('php ' . $daemonPath . ' > /dev/null 2>&1 &');
}

Small but useful detail: Why grep -c '[p]hp ...' instead of grep -c 'php ...'?

小而有用的细节:为什么grep -c ' hp…而不是grep -c 'php…?

Because while counting processes grep -c 'php ...' will be counted as a process that fits in our pattern. So using a regex for first letter of php makes our command different from pattern we search.

因为当计算grep -c 'php进程时…将被视为符合我们模式的过程。因此,对于php的第一个字母使用regex将使我们的命令与我们搜索的模式不同。

#11


0  

If you're having trouble checking for the PHP script directly, you can make a trivial wrapper and check for that. I'm not sufficiently familiar with Windows scripting to put how it's done here, but in Bash, it'd look like...

如果您在直接检查PHP脚本时遇到了麻烦,您可以做一个简单的包装并检查它。我不太熟悉Windows脚本编程,无法在这里说明它是如何实现的,但是在Bash中,它看起来像是……

wrapper_for_test_php.sh

wrapper_for_test_php.sh

#!/bin/bash
php test.php

Then you'd just check for the wrapper like you'd check for any other bash script: pidof -x wrapper_for_test_php.sh

然后,您只需检查包装器,就像检查任何其他bash脚本一样:pidof -x wrapper_for_test_php.sh

#12


0  

I have used cmder for windows and based on this script I came up with this one that I managed to deploy on linux later.

我在windows中使用了cmder,基于这个脚本,我开发出了这个我后来在linux上部署的脚本。

#!/bin/bash
 clear
 date
 while true
 do
    php -f processEmails.php
    echo "wait a little while for 5 secobds..."; 
    sleep 5
 done