From the documentation:
Answer from Cristian on Stack OverflowIn order to execute a command and have it not hang your PHP script while
it runs, the program you run must not output back to PHP. To do this,
redirect both stdout and stderr to /dev/null, then background it.
> /dev/null 2>&1 &In order to execute a command and have
it spawned off as another process that
is not dependent on the Apache thread
to keep running (will not die if
somebody cancels the page) run this:
exec('bash -c "exec nohup setsid your_command > /dev/null 2>&1 &"');
From the documentation:
In order to execute a command and have it not hang your PHP script while
it runs, the program you run must not output back to PHP. To do this,
redirect both stdout and stderr to /dev/null, then background it.
> /dev/null 2>&1 &In order to execute a command and have
it spawned off as another process that
is not dependent on the Apache thread
to keep running (will not die if
somebody cancels the page) run this:
exec('bash -c "exec nohup setsid your_command > /dev/null 2>&1 &"');
You can run the command in the background by adding a & at the end of it as:
exec('run_baby_run &');
But doing this alone will hang your script because:
If a program is started with exec 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.
So you can redirect the stdout of the command to a file, if you want to see it later or to /dev/null if you want to discard it as:
exec('run_baby_run > /dev/null &');
How to Wait for completion of shell commands execution in PHP? - Stack Overflow
Executing Python Script from PHP and wait for it.
queue - PHP shell_exec wait for script to finish? - Stack Overflow
shell script - Bash to Call PHP, Wait for PHP Process to finish? - Unix & Linux Stack Exchange
shell_exec is not the cause of your problems. It'll wait and return the output of your command. However, you mustn't start your command in the background and using nohup.
nohup is the command you are calling but as soon as it has started its child process it will exit immediatelly, thus, shell_exec will not wait for that process to be completed. You should also refrain from running the command in the background with &.
I'd first suggest not executing code from PHP but use PHP wrappers and libraries whenever possible.
One problem I see is that your processing is synchronous, this means the user will have to wait that the server responds without any clue about what is going on. He may even refresh the page which would increase the load of your server without control, and this is a very serious issue. This would enable a DOS attack.
I suggest AJAX for these long-running task. You can display something to show progress on the webpage and update it (AJAX) when it's done or switch to another page. You can even handle the case of the user quitting the page by catching that event in javascript and killing the process.
I was working on something that requires me to run a Python script with some arguments from PHP itself, and complete some task and print some output. The thing is, I tried shell_exec() and few more things mentioned in SO to run python script. But, the issue is that PHP doesn't seem to wait for my python script to complete. I need something that'll wait till the Python is done with the job. Can someone suggest me something?
EDIT : Typo in "shell_exec()" name.
UPDATE : After I re-looked at my script this morning.... seems like python can't open file. So, the PHP might not have permissions for that script. So, went ahead and gave it the perms. I added "www-data" group to that python file and changed python file's perms to 777. It still didn't work. But, the main issue right now is that Python script can't seem to be executed via apache2->Php.
Thanks everyone for all the help and hints. Appreciate it!
UPDATE 2 : I fixed the permission issue with "www-data" and it's working. THANKS EVERYONE!
PHP exec will wait until the execution of the called program is finished, before processing the next line, unless you use & at the end of the string to run the program in background.
If I'm getting you right, you're executing php scripts from inside a php script.
Normally, php waits for the execution of the exec ("php phpscript1.php"); to finish before processing the next line.
To avoid this, just redirect the output to /dev/null or a file and run it in background.
For example: exec ("php phpscript1.php >/dev/null 2>&1 &");.
How about adding.
"> /dev/null 2>/dev/null &"
shell_exec('php measurePerformance.php 47 844 [email protected] > /dev/null 2>/dev/null &');
Note this also gets rid of the stdio and stderr.
This will execute a command and disconnect from the running process. Of course, it can be any command you want. But for a test, you can create a php file with a sleep(20) command it.
exec("nohup /usr/bin/php -f sleep.php > /dev/null 2>&1 &");
Hi all I'm trying to SvtAv1EncApp tools via web interface, I try to us both exec() shell_exec() with no success , BTW I print the command and run it into the shell directly and it's works perfectly fine.
$cmd2="/usr/local/bin/ffmpeg -loglevel -8 -i "$mp4" -s 960x540 -strict -1 -f yuv4mpegpipe - | /usr/local/bin/SvtAv1EncApp --no-progress -i stdin --rc 0 -q 38 --preset 8 -b stdout 2>/var/www/vl/ffmpeg.log | /usr/local/bin/ffmpeg -loglevel -8 -y -i - -i "$mp4" -map 0:v -map 1:a:0 -c:v copy $a '".$mpa."_.mkv' & ";
shell_exec( $cmd2 ) ;
Here is the text of echo $cmd2 output
/usr/local/bin/ffmpeg -loglevel -8 -i "FHD.mp4" -s 960x540 -strict -1 -f yuv4mpegpipe - | /usr/local/bin/SvtAv1EncApp --no-progress -i stdin --rc 0 -q 38 --preset 8 -b stdout 2>/var/www/vl/ffmpeg.log | /usr/local/bin/ffmpeg -loglevel -8 -y -i - -i "FHD.mp4" -map 0:v -map 1:a:0 -c:v copy -strict -2 -c:a libopus -b:a 64k 'FHD_.mkv' &
=Update=
I kinda solve it , I don't know why but exec() successfully executed the script , I created new bash script from command line thanks to @xisonc suggesting nano /usr/local/sbin/av1c with this value
!/bin/sh
touch /var/www/vl/ffmpeg.log /usr/local/bin/ffmpeg -loglevel -8 -i "$1" -s 960x540 -strict -1 -f yuv4mpegpipe -
| /usr/local/bin/SvtAv1EncApp --no-progress -i stdin --rc 0 -q 38 --preset 8 -b stdout 2>/var/www/vl/ffmpeg.log
| /usr/local/bin/ffmpeg -loglevel -8 -y -i - -i "$1" -map 0:v -map 1:a:0 -c:v copy -strict -2 -c:a libopus -b:a 64k "$2"
On the php script i had this
$cmd2="/usr/local/sbin/av1c '$mp4' '$mpa"."_.mkv' 2>/dev/null >/dev/null & " ; exec( $cmd2 , $pid, $r ) ; var_dump( $r ) ;
var_dump returns 0 , and since the bash script are silent I don't need to see the output , now I want to change it to wok on the background it's running on background now after adding 2>/dev/null >/dev/null & at the end of the command .