从PHP启动一个守护进程


Starting a daemon from PHP

对于一个网站,我需要能够启动和停止守护进程。我现在正在做的是

exec("sudo /etc/init.d/daemonToStart start");

守护进程启动,但是Apache/PHP挂起。执行ps aux发现sudo本身变成了僵尸进程,有效地杀死了所有进一步的进程。当尝试从PHP启动daemon时,这是正常的行为吗?

是,Apache有执行/etc/init.d/daemonToStart命令的权限。我修改了/etc/sudoers文件以允许它这样做。不,我不允许Apache能够执行任何类型的命令,只是一个有限的几个允许网站工作。

无论如何,回到我的问题,有没有一种方法允许PHP启动守护进程的方式没有僵尸进程被创建?我问这个问题是因为当我做相反的事情时,停止一个已经启动的守护进程,工作得很好。

尝试将> /dev/null 2>&1 &附加到命令中。

:

exec("sudo /etc/init.d/daemonToStart > /dev/null 2>&1 &");

如果你想知道它是做什么的/为什么:

  • > /dev/null -重定向STDOUT到/dev/null(黑洞,换句话说)
  • 2>&1 -重定向STDERR到STDOUT(黑洞)
  • &分离进程并在后台运行

我也遇到过同样的问题。

我同意DaveRandom,你必须抑制每个输出(标准输出和标准错误)。但是不需要在以' & '结尾的另一个进程中启动:exec()函数不能再检查返回代码,即使有错误也会返回ok…

我更喜欢将输出存储在临时文件中,而不是"黑洞"文件。工作解决方案:

$temp = tempnam(sys_get_temp_dir(), 'php');
exec('sudo /etc/init.d/daemonToStart >'.$temp.' 2>&1');

读取文件内容后,删除临时文件:

$output = explode("'n", file_get_contents($temp));
@unlink($temp);

我从未尝试过从PHP启动守护进程,但我尝试过运行其他shell命令,遇到了很多麻烦。以下是我过去尝试过的一些方法:

  • 根据DaveRandom的回答,将/dev/null 2>&1 &附加到命令的末尾。这将把错误重定向到标准输出。然后您可以使用此输出进行调试。
  • 确保您的web服务器的用户的PATH包含您的守护脚本中所有引用的二进制文件。您可以通过调用exec('echo $PATH; whoami;)来做到这一点。这将告诉你PHP运行的用户,以及它当前的PATH变量。