Prevent waiting for command line output - php

I thought that this would run without waiting for an output:
php /scripts/htdocs/summaries.live/app/scripts/generate-pdfs.php live 1 > /dev/null 2>&1
But it's not happening. PHP's exec() function is waiting for an output. How can I work around this to prevent this from happening?

you're missing & on the end of command
php /scripts/htdocs/summaries.live/app/scripts/generate-pdfs.php live 1 > /dev/null 2>&1 &

If running something with exec, the documentation states
Note:
If a program is started with this function, in order for it to
continue running in the background, the output of the program must be
redirected to a file or another output stream. Failing to do so will
cause PHP to hang until the execution of the program ends.

Related

PHP exec command prevents echo from working

In this code:
session_write_close();
echo "reload";
flush();
// exec("/etc/init.d/streaminit stop");
// sleep(2);
// session_write_close();
// exec("/etc/init.d/streaminit start");
// //all we have to do is copy currentView into nextView to trigger a page reload
// sleep(2);
the echo of "reload" works, but if the lines below it are uncommented, nothing is echoed. I have tried many permutations of this and the conclusion is that the exec command is preventing the echo from working.
I found some discussion of exec causing problems with Apache2, and one person said that session_write_close() might prevent the problem. Evidently in this case it doesn't. Are there any known fixes for this? Am I doing something wrong?
(streaminit is a shell script that starts and stops the mjpeg_streamer. The shell commands are asynchronous (with & at the end))
I finally found this in the documentation for PHP's exec: "If a program is started with this function, in order for it to continue running in the background (my emphasis), the output of the program must be redirected to a file or another output stream. Failing to do so will cause PHP to hang until the execution of the program ends." The fix:
exec("/etc/init.d/streaminit stop > /dev/null 2>&1 &”);
For those unfamiliar (like me until a minute ago), this redirects the stdout device to /dev/null, and the 2>&1 means "send stderr output to the same place as stdout. Finally, the & means "run this command in the background". Works!

AJAX Script doesn't respond until background program ran with exec() ends

I run a background PHP program with exec() like this :
exec('/usr/bin/php bgScript.php "arg1" "arg2" > /dev/null 2>&1 &');
It works and the program does run in background.
Problem
I have Output Buffering Enabled and would like to keep it that way.
My whole script is this :
exec('/usr/bin/php bgScript.php "arg1" "arg2" > /dev/null 2>&1 &');
echo json_encode(array(
"status" => "started"
));
When an AJAX request is made to the file above, the process is started and is in background. I assume this because, further requests to the server returns data and doesn't wait for the previous AJAX script to finish.
But, the problem is that the JSON data is not outputted until the background process is completed.
Since the program is made to run in the background, shouldn't the JSON Data be outputted without waiting for the exec() to end ? I don't know how to say this techinically (Forgive me) : Why does the Output Buffer continue until exec() ends ?
How can I make the script output the JSON Data right after the program is started in the background and close the connection between the AJAX script and browser ?
The command does not run in the background if it's stdio is not redirected. From the official documentation
Note:
If a program is started with this function, in order for it to continue running in the background, the output of the program must be redirected to a file or another output stream. Failing to do so will cause PHP to hang until the execution of the program ends.
There are several methods to alter this behavior in Unix like systems you can run the command with command >/dev/null & on windows you can use start command.

get PID of PHP file executed with shell_exec with continuous output

I do have a PHP script which has a continuous ouptput (written to tmp file for logging). So far, I started the script right from the shell, but now, I would like to start it via shell_exec:
shell_exec("file.php >> /path/to/log 2>&1 &");
But shell_exec always return null instead of the PID.
How can I get the PHP process ID and keep the output written to the file?
Thanks in advance.
Look into proc_open and proc_get_status instead.

How to email output from shell_exec()?

With cron jobs, the output of the file being executed is emailed to me. I recently discovered via this answer that it's possible to asynchronously execute a PHP file using the shell_exec() function. Per the above answer, I've been using the following command:
shell_exec('php /file/path.php parameter1 parameter2 > /dev/null 2>/dev/null &');
I think what is of most interest with regards to this question is the stuff at the end:
> /dev/null 2>/dev/null &
Is there any way to change that so that the output is emailed, like with a cron job?
The line
> /dev/null 2>/dev/null &
Essentially sends the output to a null file. If you take that bit off, the output will be sent to the standard out, which should in turn should email you the results assuming you run it with a cron job.
So,
shell_exec('php /file/path.php parameter1 parameter2');
If you're not running it with a cron job, you'll need to build in the email functionality to the script itself.
First off, shell_exec() is not asynchronous. Execution of the PHP code will be suspended until the shell_exec() call has terminated.
This: > /dev/null tells the shell to redirect stdout from the process being executed to /dev/null, which means it disappears. This: 2> /dev/null does the same, but for stderr in stead of stdout.
If you remove these parts of the shell_exec() call, the call will return whatever is written to stdout:
$result = shell_exec('php /file/path.php parameter1 parameter2');
mail('me#email.com', 'Shell output', $result);
There are also other alternatives to shell_exec() that may suit your needs better. For example popen()andproc_open()` allow more fine grained control over input and output.
Also, since you are executing a PHP script, you may be able to simply use include() or require(), depending on how the script is written. Another option would be to read the file and then execute the PHP code using eval().
Use :
| mail -s "Result of cron job" myemail#company.com
At the end of your command. Also, you can pipe stderr and stdout into stdout 2> &1 | mail....
That should do the trick. Maybe because you use shell_exec("... &"), you'll have to wrap the whole php /file/... | mail -s "result" myemail#company.com in a subshell. like:
shell_exec('(php /file/path.php parameter1 parameter2 2> &1 | mail -s "Result of cron job" myemail#company.com) &')
This is a rather ugly way to get the output to send a message and I'd advise in favor of refactoring the outer call of shell_exec to read stderr and stdout, craft a message and send that to yourself. Meanwhile the | mailsolution should do the trick.
Happy mailing !

PHP CLI process not terminating when done

I have this in one PHP file:
echo shell_exec('nohup /usr/bin/php -f '.CRON_DIRECTORY.'testjob.php > /dev/null 2>&1 &');
and in testjob.php I have:
file_put_contents('test.txt',time()); exit;
And it all runs just dandy. However if I go to processes it's not terminating testjob.php after it runs.
(Having to post this as an answer instead of comment as stackoverflow still won't let me post comments...)
Works for me. I made testjob.php exactly as described, and another file test.php with just the given line (except I removed CRON_DIRECTORY, because testjob.php was in the same directory for me).
To be sure I was measuring correctly, I added "sleep(5)" at the top of testjob.php, and in another window I have:
watch 'ps a |grep php'
running. This happens:
I run test.php
test.php exits immediately but testjob.php appears in my list
After 5 seconds it disappears.
I wondered if shell might matter, so I switched from bash to sh. Same result.
I also wondered if it might be because your outer script is long-running. So I put "sleep(10)" at the bottom of test.php. Same result (i.e. testjob.php finishes after 5 seconds, test.php finishes 5 seconds after that).
So, unhelpfully, your problem is somewhere other than the code you've posted.
Remove & from the end of your command. This symbol says nohup to continue running in background, thus shell_exec is waiting for task to complete... and waiting... and waiting... till the end of times ;)
I don't even understan why would you perform this command with nohup.
echo shell_exec('/usr/bin/php -f '.CRON_DIRECTORY.'testjob.php > /dev/null 2>&1');
should be enough.
You're executing PHP and make that execution a background task. That means it will run in background until it is finished. shell_exec will not kill that process or something similar.
You might want to set an execution limit, PHP cli has a setting of unlimited by default. See as well set_time_limit PHP Manual;
So if you wonder why the php process does not terminate, you need to debug the script. If that's too complicated and you're unable to find out why the script runs that long, you might just want to terminate the process after some time, e.g. 1 minute.

Categories