i'm trying to spawn a daemon-like process from php on a unix environment, keep the pid for reference and keep it completely independent from httpd processes. This is useful for controlling middleware applications from administrative backoffices. I want to keep it generalized to reuse for any command, i don't want to write a .sh for every command.
using php's exec() i'm running this command:
$command = "java /myApp/TestInfiniteLoop";
$log = "/myApp/myLog.txt";
$echos = null;
$fullCommand = "bash -c 'nohup $command < /dev/null > $log 2>&1 & echo $! & exit' & echo $!";
exec($fullCommand, $echos);
$pid = (int)$echos[0] + 2;
It returns $pid but does not spawn process (or kills it immediately...).
If i run the $fullCommand on a bash shell it works perfectly. I can close the bash and everything keeps running as expected.
If i take out the "nohup " it works (but pid is +1 and not +2), but as soon as you stop httpd the process get's killed too...
What is the correct way to make it work?
If possible can anyone correct it to get the pid directly? i'm assuming it is the second p开发者_开发技巧rocess from the bash (+2) call, but it is possible (though not probable, i know...) that it wouldn't be the same.
PS: i've been testing it on Mac and Linux environments.
You almost have it. I think you may have too many pipes going on and the http process isn't disconnecting because it's waiting for output. This will work:
$command = 'java /myApp/TestInfiniteLoop';
exec('nohup '.$command.' >> /myApp/myLog.txt 2>&1 & echo $!', $pid);
$pid = (int)$pid[0];
I do this with PHP scripts all the time, you don't have to write a shell script.
One thing I've done in the past is have a separate process (like a python or c application) already running that watches either a text file or a database. The php process either writes to the file or database, and the other process, which is running as a separate user with separate permissions is polling that file or database. When it sees what it's looking for, it does whatever it needs to, reporting progress back to the file or database. That way you have a lot more freedom and flexibility in what the app does (it could write its pid to the file, for example, so that php knows what it is).
I would look into something like gearman api, which is designed to create long running processes (and then spawn actions from that) rather than try to spawn applications yourself and try to figure out the pid (it will have the side benifit of being a lot more cross platform as well). The +2 pid will definitely have race condition problems.
精彩评论