I have to run in background a shell command (that uses a ruby script from /usr/local/bin) using php (from a html/php form) and ignoring all the output.
I've tried unsuccessfully exec(), system(), shell_exec().
Also executing the script (not written by me, script link - I don't know ruby) in the terminal and redirecting the standard output to /dev/null, it keeps showing real-time infos about the download progress and speed of the download until it's completed.
I suppose it's because of the script and I've read somewhere that proc_open() can help but I don't know how to use it.
EDIT
Also adding "&" to the command (in the terminal) it keeps showing real-time infos about the download progress and speed of the download until it's completed.
/usr/local/apache2/htdocs$ ls
1.php ruby_prog.rb
1.php:
<div>hello</div>
<div>
<?php
$command = 'ruby ruby_prog.rb';
$output = [];
exec($command, $output, $return_var);
echo($output[0]);
?>
</div>
ruby_prog.rb:
puts 'world'
url:
http://localhost:8181/1.php
output in browser:
hello
world
source html:
<div>hello</div>
<div>
world</div>
You can check the value of $return_var--if it's 0, then the ruby program ran successfully; if it's non-zero, there was an error.
If you don't want any output, then you can use the command:
ruby ruby_prog.rb > /dev/null 2>&1
The > sends stdout to /dev/null, which is a sink, i.e. it acts like a blackhole, and 2>&1 says to send stderr(2) to wherever stdout(&1) goes.
Related
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.
I'm trying to make a simple script in PHP which download a video of youtube, at the first moment I tried some classes I found on web but unsuccessful, so I decide to use youtube-dl program and call it from to my script.
The big problem is: apparently the process is killed when the page loads in the browser and the download is interrupted.
The most curious thing is that if I execute the script like that: php page.php, the script works nicely but the browser doesn't work.
I note the same thing with wget command, the process also killed.
The code is something like:
<?php
exec("youtube-dl -o /var/www/YT/video.flv https://youtube....");
?>
and
<?php
exec("wget http://link");
?>
*Both youtube-dl and wget are in the same directory from script, I tried too redirect output to /dev/null and fork process mas both no success.
I would try executing it at the background.
<?php
exec("youtube-dl -o /var/www/YT/video.flv https://youtube.... > /dev/null 2>&1 &");
?>
If that works then what it's happening is that your php script ends before youtube-dl
I'm working on a web application that needs to send a lot of HTTP requests and update the table, this will block the PHP from executing. So I though I might have to write a separate PHP script and run it via my main application. I tried Exec but still the program waits until the script is executed.
exec('php do_job.php');
I even tried redirecting the output to a file as PHP.Net suggests:
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.
$result = exec('php do_job.php > output.txt &',$output);
But still no success ... Further down the same page I came accross this:
$command = 'php do_job.php';
$shell = new COM("WScript.Shell");
$shell->run($command, 0, false);
Still no sucess ... Lastly I tried:
pclose(popen("start /B ". $command, "r"));
What am I doing wrong here?
I'm developing my app on localhost (XAMPP - Windows), later I'll be releasing it on a Linux host. My last resort would be to run the script via CRON jobs. Is this the only way?
By just adding & at the end of command you can run any command in background. Here I'm redirecting o/p to /dev/null to avoid hang(For Linux).
exec('php do_job.php > /dev/null &');
If you want see the o/p of the command you can redirect it to a file.
exec('php do_job.php > full_path_to_file &');
You can easily use exec() or shell_exec() to execute a system command, like ls -l /var/www/mysite and then output the result of the command.
How would one execute and display the result of a command that periodically prints information out to the console?
You have a simply Python script. If you run the script from the console, it simply prints out some type of information to the console every 10 seconds forever until you force-quit the script.
How could use PHP to execute this python command and somehow capture and stream the output into the browser in realtime? Is something like this possible? I'm thinking there would have to be some sort of Ajax involved but I'm not sure.
I tried doing something like this:
python myscript.py > output.txt
And then I was planning on maybe using Ajax to periodically tail or cat the content of the output.txt and display in the browser. But output.txt doesn't appear to have any content added to it until after the script has been force-quit.
You don't see any output to output.txt because it's being buffered. For python there's an option to make it line-buffered. From the manpage:
-u Force the binary I/O layers of stdin, stdout and stderr to be unbuffered. The text I/O layer will still be
line-buffered.
So your command would then become:
python -u myscript.py > output.txt
For PHP the flush function should help you.
I am trying to invoke a script which takes several seconds (web services with 3rd party) using the PHP exec call. After much struggling, I reduced this to the classic hello world example. The calling script looks like:
exec('/usr/bin/php /home/quote2bi/tmp/helloworld.php > /tmp/execoutput.txt 2>&1 &');
When I run this, the output execoutput.txt contains a copy of the invoking script page, not hello world as I expected.
Why can't I get this PHP script to execute using exec? Note that when I change the command to something like ls -l, the output is a directory listing as expected. btw, in case it matters, I did chmod the called script to 755...
Update - I moved the exec call to the end of the calling script and at least now I don't see the calling script executed in the output. Thx to posters and I will try some of these ideas.
Help!
Thanks
Steve
I had this issue also and it turns out this is a bug in php (#11430). The fix is to use php-cli when calling another php script within a php script. So you can still use exec but rather than use php use php-cli when calling it in the browser:
exec("php-cli somescript.php");
This worked for me.
What exec is doing is taking the rightmost command and appending it to your destination. If you have the shebang line in your php script, you shouldn't need to include the binary directive of the php interpreter.
if you just want the script's output, try:
exec('/home/quote2bi/tmp/helloworld.php > /tmp/execoutput.txt 2>&1 &')
however if you do not want the errors to be in the file, you should redirect the STDERR prior to outputting to the file. Like so:
exec('/home/quote2bi/tmp/helloworld.php 2> /dev/null > /tmp/execoutput.txt')
the above should only output the "Hello World" to the execoutput.
Edit:
Interesting you are getting this behaviour. You stated the command "ls" worked. Try making an alias for this and forward it to a file like so:
alias pexec='php /home/quote2bi/tmp/helloworld.php'
then
exec('pexec > /tmp/execoutput.txt 2>&1 &')
it seems to be a problem with the way exec handles input as opposed to the shell itself.
-John
The problem is with PHP itself, it treats everything as $argv in the script. It doesn´t redirect the output to a file ou to /dev/null.
I faced the same problem some time ago. What I did is to create a runscript.php in /opt/php-bin and then inside this script run what It should be running. Something like this:
$script = $argv[1]
$params = implode(' ', array_slice($argv, 2));
$cmd = "{$script} {$params} > /dev/null &";
$output = array();
$return = 0;
exec("php {$cmd}", $output, $return);
exit((int)$return);
And then you call it using:
exec('/opt/php-bin/runscript.php /path/to/your/script.php arg1 arg2')
It´s the only way I managed to get this working.
To avoid the stated problems of PHP in this area, why not put this in inside a shell script? PHP can then execute the shell script which has all the redirections handled internally.
If you need to dynamically change things, then why not write the shell script and then execute it (and of course, clean up afterwards)?
if you are just simply running a php script one possible way to execute the entire code is to use the include() that will run the php file and output any results. You cannot direct the output to a text file but it should appear in the browser window if you're Hello World php script looks like
<?php echo "Hello World!"; ?>
then it will spit that out in the browser. So your second code would look like
<?php include("helloWorld.php"); echo " PHP ROCKS";?>
resulting in a page that would look like,
Hello world! PHP ROCKS
This runs as if you run the script from browser.
This came across while working on a project on linux platform.
exec('wget http://<url to the php script>)
Hope this helps!!