Starting a daemon from PHP
Asked Answered
E

3

11

For a website, I need to be able to start and stop a daemon process. What I am currently doing is

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

The daemon process is started, but Apache/PHP hangs. Doing a ps aux revealed that sudo itself changed into a zombie process, effectively killing all further progress. Is this normal behavior when trying to start a daeomon from PHP?

And yes, Apache has the right to execute the /etc/init.d/daemonToStart command. I altered the /etc/sudoers file to allow it to do so. No, I have not allowed Apache to be able to execute any kind of command, just a limited few to allow the website to work.

Anyway, going back to my question, is there a way to allow PHP to start daemons in a way that no zombie process is created? I ask this because when I do the reverse, stopping an already started daemon, works just fine.

Endor answered 5/12, 2011 at 14:47 Comment(2)
Shouldn't there be a start argument?Renner
True, I forgot to add that to the question. In my code, I do have it. But, I'll edit the question for completeness.Endor
S
13

Try appending > /dev/null 2>&1 & to the command.

So this:

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

Just in case you want to know what it does/why:

  • > /dev/null - redirect STDOUT to /dev/null (blackhole it, in other words)
  • 2>&1 - redirect STDERR to STDOUT (blackhole it as well)
  • & detach process and run in the background
Schramm answered 5/12, 2011 at 14:52 Comment(4)
Thanks for the further explanation, but because the output is blackholed, any code that should have been executed after the daemon has started, is onmitted aswell. I have to check if the process has started, but that code is never fired...Endor
When you start a process using this method, it should output the PID of the process that was created. You can take this, and then (for example) execute ps | grep $pidOfProcessYouJustStarted to make sure it is running.Schramm
Actually, you could just execute ps | grep /etc/init.d/daemonToStart to do the same thing...Schramm
I know, I am already doing that. ;) It seemed that that code was never executed though, as my browser didn't present me with an alert with the result value I presented. But my logs show that the code is actually being run. So thanks again.Endor
L
2

I had the same problem.

I agree with DaveRandom, you have to suppress every output (stdout and stderr). But no need to launch in another process with the ending '&': the exec() function can't check the return code anymore, and returns ok even if there is an error...

And I prefer to store outputs in a temporary file, instead of 'blackhole'it. Working solution:

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

Just read file content after, and delete temporary file:

$output = explode("\n", file_get_contents($temp));
@unlink($temp);
Literate answered 12/6, 2014 at 12:34 Comment(0)
S
0

I have never tried starting a daemon from PHP, but I have tried running other shell commands, with much trouble. Here are a few things I have tried, in the past:

  • As per DaveRandom's answer, append /dev/null 2>&1 & to the end of your command. This will redirect errors to standard output. You can then use this output to debug.
  • Make sure your webserver's user's PATH contains all referenced binaries inside your daemon script. You can do this by calling exec('echo $PATH; whoami;). This will tell you the user PHP is running under, and it's current PATH variable.
Selfreproach answered 5/12, 2011 at 14:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.