0

我是一名 PHP 开发人员,对 shell 脚本知之甚少......所以我很感激这里的任何帮助。

我有四个需要在服务器后台运行的 php 脚本。我可以很好地启动它们——它们工作得很好——我可以通过查看它们的 PID 来杀死它们。

问题是我需要我的脚本不时终止进程并重新启动它们,因为它们维护着长期存在的 HTTP 请求,这些请求有时会被另一方终止。

但是我不知道如何编写一个命令来找到这些进程并在不手动查找 PID 的情况下杀死它们。

我们将从一个启动命令开始:

/usr/local/php5/bin/php -f /home/path/to/php_script.php > /dev/null &

有没有办法“分配”一个PID,所以它总是一样的?或者给这个过程一个名字?我将如何编写新命令?

谢谢!

4

5 回答 5

4

不,您不能“分配”进程 PID;相反,您应该像“真正的”守护进程那样做:让您的脚本将自己的 PID 保存在某个文件中,然后在需要终止时从该文件中读取它。

另一种选择是使用像supervisor这样的东西,它以一种非常好的方式为你处理所有这些。

更新 - 主管配置

由于我提到了主管,我还在这里发布了一个简短的主管配置文件,应该可以完成这项工作。

[program:yourscriptname]
command=/usr/local/php5/bin/php -f /home/path/to/php_script.php

在这里查看更多配置选项

然后你可以像这样使用它:

# supervisorctl status

显示进程状态。

# supervisorctl start yourscriptname

开始你的脚本

# supervisorctl stop yourscriptname

停止你的脚本

更新 - 真实世界的主管配置示例

首先,确保你的/etc/supervisor/supervisord.conf.

[include]
files = /etc/supervisor/conf.d/*.conf

如果没有,只需添加这两行并

mkdir /etc/supervisor/conf.d/

然后,为要启动的每个进程创建一个配置文件:

/etc/supervisor/conf.d/script1.conf

[program:script1]
command=/usr/local/php5/bin/php -f /home/path/to/php_script.php
stdout_logfile=/var/log/script1.log
stderr_logfile=/var/log/script1-error.log

/etc/supervisor/conf.d/script2.conf

[program:script2]
command=/usr/local/php5/bin/php -f /home/path/to/php_script2.php
stdout_logfile=/var/log/script2.log
stderr_logfile=/var/log/script2-error.log

...等等,等等..为您的所有脚本。

(请注意,您不需要尾随 & 因为主管将为您处理所有守护进程;事实上,您不应该执行在主管内部自我守护进程的程序)。

然后你可以开始他们:

supervisorctl start all

或者只是一个类似的东西:

supervisorctl start script1

从 php 启动主管

当然,您可以使用上面的两个命令启动/停止主管控制的进程,即使是在脚本内部也是如此。

但是请记住,您将需要 root 权限,并且允许例如非常冒险。在服务器上以 root 身份执行命令的网页..

如果是这种情况,我建议您查看有关如何以普通用户身份运行主管的说明(我从未这样做过,但您也应该能够以 www-data 用户身份运行它......)。

于 2012-10-17T22:14:21.460 回答
3

解决此问题的规范方法是让进程将其 PID 写入已知位置的文件中,然后任何实用程序脚本都可以查找该文件、读取 PID 并操作该进程。向脚本添加一个命令行参数,该参数给出要写入的 PID 文件的名称。

于 2012-10-17T22:13:12.677 回答
0

好的!因此,对于对 shell/bash 什么脚本一无所知的我来说,这一直是一个令人头疼的问题……

@redShadow 的回应本来是完美的,但我的托管服务提供商不会让我访问 /etc/supervisor/ 目录。正如他所说,你必须是 root - 即使使用sudo是管理员也不会让我在那里有任何机会......

这是我想出的:

kill -9 `ps -ef | grep php | grep -v grep | awk '{print $2}'`

因为我正在执行的唯一类型的命令显示在top命令中,因为php该命令循环通过正在运行的进程,找到php命令及其相应的 PID 并杀死它们!呜呜!!

于 2012-10-18T22:24:17.937 回答
0

解决此问题的方法是使用ps aux,这将使用调用它们的命令显示所有进程。这当然假定这 4 个脚本是不同的文件,或者可以由调用它们的命令唯一标识。通过一个 grep 管道,你就准备好了ps aux | grep runningscript.php

于 2012-10-17T22:17:59.087 回答
0

我所做的是让我的脚本检查我命名为“run.txt”的文件。如果不存在,则退出。然后只需重命名该(空)文件,我就可以停止所有脚本。

于 2013-01-12T11:19:25.773 回答