从PHP启动守护程序

从PHP启动守护程序,php,daemon,zombie-process,Php,Daemon,Zombie Process,对于一个网站,我需要能够启动和停止一个守护进程。我现在正在做的是 exec("sudo /etc/init.d/daemonToStart start"); 守护进程已启动,但Apache/PHP挂起。执行ps aux显示sudo本身变成了一个僵尸进程,有效地扼杀了所有进一步的进展。尝试从PHP启动daeomon时,这是正常行为吗 是的,Apache有权执行/etc/init.d/daemonToStart命令。我修改了/etc/sudoers文件以允许它这样做。不,我没有允许Apache执行

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

exec("sudo /etc/init.d/daemonToStart start");
守护进程已启动,但Apache/PHP挂起。执行
ps aux
显示
sudo
本身变成了一个僵尸进程,有效地扼杀了所有进一步的进展。尝试从PHP启动daeomon时,这是正常行为吗

是的,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(同时将其黑洞化)
  • &
    分离进程并在后台运行

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

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

    • 我也有同样的问题

      我同意DaveRandom,您必须抑制每个输出(stdout和stderr)。但无需在另一个进程中启动以“
      &
      ”结尾的程序: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);
      

      感谢您的进一步解释,但是由于输出是blackholed,因此应该在守护进程启动后执行的任何代码也会被重新编写。我必须检查流程是否已启动,但该代码从未被触发……当您使用此方法启动流程时,它应输出所创建流程的PID。您可以这样做,然后(例如)执行您刚刚启动的
      ps | grep$pidofProcess
      以确保它正在运行。实际上,您可以只执行
      ps | grep/etc/init.d/daemonToStart
      来做同样的事情……我知道,我已经在做了。;)但是,似乎从未执行过该代码,因为我的浏览器没有向我显示带有我显示的结果值的警报。但是我的日志显示代码实际上正在运行。再次感谢。难道不应该有一个
      start
      参数吗?是的,我忘了把它添加到问题中。在我的代码中,我确实有它。但是,为了完整性,我将对问题进行编辑。