PHP exec background never finish - php

I want to process my access log in php - checking some IPs, which are leeching content and so on, everything in PHP, running as CLI. I tried to make following, but it never pass exec tail -f, so, actually I can not process the data. Any help appreciated.
$log = '/var/log/lighttpd/web.org-access.log';
$pipefile = '/www/web.org/tmp/fifo.tmp';
if(file_exists($pipefile))
if(!unlink($pipefile))
die('unable to remove stale file');
umask(0);
if(!posix_mkfifo($pipefile,0777))
die('unable to create named pipe');
exec("tail -f $log > $pipefile 2>&1 &"); //I tried nohup and so on...
//exec("varnishncsa $log > $pipefile 2>&1 &"); //will be here instead tail -f
echo "never comes here"; //never shows up
If possible, I want to do it just in PHP, no bash/tcsh scripting (I know how to do it using those).
Thanks.

If you want exec to start a background process, you will have to redirect its output.
Quote from the manual:
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.
Notice the full syntax description:
string exec ( string $command [, array &$output [, int &$return_var ]] )
Source: http://www.php.net/manual/en/function.exec.php

Related

How to check bash shell finished in php

I am having difficulty processing bash shell in php.
My problem is as below.
I have 3 tasks corresponding to 3 files bash shell (task1.sh, task2.sh, task3.sh). When task1.sh finishes processing, task2.sh will automatically execute, when task2.sh finishes processing, task3.sh will automatically execute.
Initially, I wrote a file called task.sh and embedded task1.sh, task2.sh, task3.sh into it. But I want to embed these 3 tasks into a php file.
For example: I create task.php and do the following:
If task1.sh fails, it will display popout (alert) error message.
If task1.sh processing is complete then task2.sh will continue to be automatically done.
The processing of task2.sh and task3.sh is similar to the above.
All 3 tasks I want to run backgroud. The problem is that when I run the background bash shell, I will not be able to check the failed error statement (the result always returns to 0).
I have learned a lot and consulted many documents but it did not help me.
I hope you can support me.
Sorry, my english very poor.
You may use the $retval argument of exec().
<?php
exec('task1.sh', $output, $retval);
if ($retval !== 0) {
// task 1 failed
exit('Error running task1: ' . implode("<br/>\n", $output));
}
exec('task2.sh', $output, $retval);
if ($retval !== 0) {
// task 2 failed
exit('Error running task1: ' . implode("<br/>\n", $output));
}
exec('task3.sh', $output, $retval);
if ($retval !== 0) {
// task 3 failed
exit('Error running task1: ' . implode("<br/>\n", $output));
}
You can simply use the function:
exec ( string $command [, array &$output [, int &$return_var ]] ) : string
With:
output :
If the output argument is present, then the specified array will be filled with every line of output from the command. Trailing whitespace, such as \n, is not included in this array. Note that if the array already contains some elements, exec() will append to the end of the array. If you do not want the function to append elements, call unset() on the array before passing it to exec().
return_var :
If the return_var argument is present along with the output argument, then the return status of the executed command will be written to this variable.
Thus you could use $output and $result_var to check the execution errors of your shells.
Regards

How to 'output' from a php script called by exec or shell_exec?

I have this line of code to execute a background task (convert several pngs to jpg)
exec("nohup path/to/php path/to/convertToJpg.php >> path/to/convert_to_jpg.log > /dev/null &");
Now I am writing the convertToJpg.php script and I can't figure out how to output information from there so that it will be logged into the convert_to_jpg.log.
When I try to google it all I come up with is how to call a php script from exec or shell_exec, since the words used to describe the two situations is almost the same.
For Clarification
An extra quote got into my code when copying it over to SO. I have fixed it. In my original code the convertToJpg.php is being called as expected, confirmed by error_logs placed in it to check.
A couple answers have pointed to the $output argument in exec(). As I understand it, that totally defeats the purpose of shell redirection using the >> path/to/convert_to_jpg.log.
My question is not how to get the output from the exec() command, but what code do I use to actually output(verb) from the convert_to_jpg.log
More Clarification
If I call
exec("nohup path/to/php path/to/convertToJpg.php >> path/to/convert_to_jpg.log > /dev/null &");
or
$results = shell_exec("path/to/php path/to/convertToJpg.php > /dev/null");
echo $results;
or
$results = "";
exec("path/to/php path/to/convertToJpg.php > /dev/null", $results);
print_r($results);
It doesn't matter which one.
Here is convertToJpg.php
<?php
echo "Will this be in $results?"; // No, this did not end up in results.
error_log("error logs are being logged, so I know that this php file is being called");
//I have tested echo, but that does not work.
//What php function do I use so that a string will be captured in the $output of an exec() call?
?>
$output = "";
$return_var = "";
exec("nohup path/to/php path/to/convertToJpg.php >> path/to/convert_to_jpg.log > /dev/null &", $output, $return_var);
$output
If the output argument is present, then the specified array will be filled with every line of output from the command. Trailing whitespace, such as \n, is not included in this array. Note that if the array already contains some elements, exec() will append to the end of the array. If you do not want the function to append elements, call unset() on the array before passing it to exec().
$return_var
If the return_var argument is present along with the output argument, then the return status of the executed command will be written to this variable.
http://php.net/manual/en/function.exec.php
Ok, I figured it out!
To answer the question plain and simply, use either echo or print.
This was the first thing I tried, but it didn't work, which made me think it was some other function that I was supposed to call. (I obviously haven't worked with this much)
The real problem I was having was the > /dev/null, which was discarding all output. Once I deleted that, it fine. Explained here: What is /dev/null 2>&1?
I had at some point done a copy/paste without really understanding what that did...
And because I was blaming the wrong thing I ended up with this off base question.

Read output from a Python command in a PHP webapp

I'm trying to read python output from a php webapp.
I'm using $out = shell_exec("./mytest") in the php code to launch the application, and sys.exit("returnvalue") in the python application to return the value.
The problem is that $out doesn't contain my return value.
Instead if I try with $out = shell_exec("ls"), $out variable contain the output of ls command.
If I run ./mytest from terminal it works and I can see the output on my terminal.
sys.exit("returnvalue")
Using a string with sys.exit is used to indicate an error value. So this will show returnvalue in stderr, not stdout. shell_exec() only captures stdout by default.
You probably want to use this in your Python code:
print("returnvalue")
sys.exit(0)
Alternatively, you could also use this in your PHP code to redirect stderr to stdout.
$out = shell_exec("./mytest 2>&1");
(In fact, doing both is probably best, since having stderr disappear can be quite confusing if something unexpected happens).

Returning a success or failure from ffmpeg

I have some code executed in PHP after meeting some criteria through if/then statements which looks something like this:
if(in_array($ext,$video)&&($ext!=="mp4")){
exec("ffmpeg -i ".$fileName.".".$ext." -s 640x360 ".$fileName.".mp4");
/*
if(successful){
unlink($fileName.$ext);
$status="Video entry approved. File converted.";
}
*/
}
As you can see, the issue I'm having is trying to figure out what should go in place of if(successful). The point of this section of the code is to check the files extension against an array of known extensions that are in video format, and that aren't already in the mp4 format. If it passes this check, ffmpeg should run and convert to mp4.
So a few questions here. Firstly, how can I return a status to tell me if it is converting, succeeded, or failed? Secondly, how can this be run asynchronously? That is, if I wanted to convert multiple files, would I be able to do so? Would I be able to limit ffmpeg to ensure it does not take up all of my server's processing power and inadvertently bring the site to a grinding halt?
Or is there a better way to go about converting files than this? I'm pretty sure my method must be crude.
EDIT: In addition to this, how does one run ffmpeg in the background, so that the page can be closed, and/or another instance from the same page can be started up by the user for multiple simultaneous conversions? Is it possible to include a real-time progress status of each conversion?
I like your use of exec. Did you happen to notice the php.net entry for that command? It's signature looks like this:
string exec ( string $command [, array &$output [, int &$return_var ]] )
You're using the $command parameter, but not $output or $return_var. So you basically have two choices here:
1 - Add the $output parameter to your exec command and print_r. Once you know the return you can use that information to help you with your logic. (The $output parameter is filled with any output that would have printed to the console had you run the command on the console.) Note that you may have to add the option -loglevel 'verbose' to see useful output.
exec("ffmpeg -i -loglevel 'verbose' ".$fileName.".".$ext." -s 640x360 ".$fileName.".mp4", $my_output_var);
print_r($my_output_var);<br>
2- Add $output and $return_var, then check to make sure $return_var is equal to 0 (which means the command executed successfully). A list of return vars can be found here:
exec("ffmpeg -i ".$fileName.".".$ext." -s 640x360 ".$fileName.".mp4", $my_output_var, $var);
if($var == 0){
// do something
}

How to know when exec() function is finish?

I have an exec function in php file that execs a bash script. It script calls fmpeg to transcode a video file.
How can I know when transcoding is finish??
$script = "/opt/lamp../name.sh"
exec("$script $videoIn $id")
I will try using next code but it doesn't workd.
if (exec("$script $videoIn $id"))
{
//print on screen that the video has been transcoded
}
The function exec() will return when the executed command is finished. My guess is that the command fails somehow (possibly because you're not using escapeshellcmd() and escapeshellarg()).
Your php script waits for the exec'd command to be finished before going on.
exec does not return the command's return value.
string exec ( string $command [, array &$output [, int &$return_var ]] )
you have to provide a var where that value will be written.

Categories