I'm trying to run in background two bash command using exec function.
$action[] = "/path/script1 par1 > log1 2>&1";
...
$action[] = "/path/script2 par2 > log2 2>&1";
...
$cmd = "( " .implode(' && ',$action). " ) &";
exec($cmd);
script1 and script2 are bash scripts.
Scripts are properly executed and their output is correctly saved in their log files, but my application hangs. It seems that last & doesn't work.
I have already tried:
$cmd = "bash -c \"" .implode(' && ',$action). "\" &";
If I run a single command, it works in background.
I captured $cmd and if I run:
( /path/script1 par1 > log1 2>&1 && /path/script2 par2 > log2 2>&1 ) &
from command line, it works in background.
I'm using Apache/2.0.52 and PHP/5.2.0 on Red Hat Enterprise Linux AS release 3 (Taroon Update 2)
The answer is hidden in the PHP exec documentation:
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.
Add a redirection to the top level of your command line:
exec( "bash -c \"( ./script1 par1 > log1 2>&1 && ./script2 par2 > log2 2>&1 ) \" >/dev/null 2>&1 & " );
and without bash -c:
exec( "( ./script1 par1 > log1 2>&1 && ./script2 par2 > log2 2>&1 ) >/dev/null 2>&1 & " );
Tested with PHP 5.3.3-7 (command line invocation): Program hangs before adding the redirect operators, and terminates afterwards.
Related
To run one command in the background, it works well.
$cmd = 'ffmpeg -re -i ./97.mp4 -vcodec copy -acodec copy -f flv -y rtmp://example.com/c/190843?auth_key=7e2682b5 > output 2>&1 </dev/null &';
exec($cmd, $output, $return_var);
Then I need to sleep for some time before the ffmpeg command. I refer to How do I run multiple background commands in bash in a single line? which works well directly in the bash console.
While not works in the below PHP script, which will return when the bash command finishes running.
$cmd = '(sleep 5; ffmpeg -re -i ./97.mp4 -vcodec copy -acodec copy -f flv -y rtmp://example.com/c/190843?auth_key=7e2682b5 > output 2>&1 </dev/null) &';
exec($cmd, $output, $return_var);
I think you also need to handle sleep's stdout/stderr.
( sleep 5 > /dev/null 2>&1; ...; ) &
Or you can put the redirection after ( ... ):
( sleep 5; ffmpeg ...no redir here...; ) < /dev/null > /dev/null 2>&1 &
To run multiple commands from on bash command; concatenate using &&.
For instance:
sleep 5 && echo hello && sleep 2 && echo world
This trick can be particularly useful in cron tasks to be able to sequence multiple items within the same minute, as a different sleep value can be used as an offset before starting the command.
I have a bash script that calls liquidsoap like so
/bin/sh -c "echo \$\$ > \"${sdir}/pid/${sfile}.pid\" && exec liquidsoap \"${sdir}/liq/${sfile}.liq\" >/dev/null 2>&1 || rm \"${sdir}/pid/{$sfile}.pid\"" &
(For readability, it might look like this with variables filled in)
/bin/sh -c "echo \$\$ > \"/radio/pid/station.pid\" && exec liquidsoap \"/radio/liq/station.liq\" >/dev/null 2>&1 || rm \"/radio/pid/station.pid\"" &
In PHP, the script is called with
return shell_exec("{$this->streamBase}/scripts/{$this->streamName} start config {$stationConfig}");
My problem is, I just had to restart Apache, and when I did, it also killed the liquid soap instances. I would like to get it to run fully independent of Apache such that I could restart Apache and they would keep running.
I'm not sure how I can achieve that.
EDIT:
I've tried changing
/bin/sh -c "echo \$\$ > \"${sdir}/pid/${sfile}.pid\" && exec liquidsoap \"${sdir}/liq/${sfile}.liq\" >/dev/null 2>&1 || rm \"${sdir}/pid/{$sfile}.pid\"" &
to
(/bin/sh -c "echo \$\$ > \"${sdir}/pid/${sfile}.pid\" && exec liquidsoap \"${sdir}/liq/${sfile}.liq\" >/dev/null 2>&1 || rm \"${sdir}/pid/{$sfile}.pid\"" & ) &
and
nohup /bin/sh -c "echo \$\$ > \"${sdir}/pid/${sfile}.pid\" && exec liquidsoap \"${sdir}/liq/${sfile}.liq\" >/dev/null 2>&1 || rm \"${sdir}/pid/{$sfile}.pid\"" &
Neither keep liquidsoap running if I restart (or stop/start) Apache. When Apache stops, so do those processes.
for an exit code to be propogated up the chain the parents and grandparents must exist, and if you kill the grandparent, aka apache, yes, you kill the children and grandchildren unless they leave the family and become daemons.
I have main php script on web-server nginx+php-fpm and try to run another php script in background using GET request from web-browser. Line code in main.php to call detect.php:
exec("/usr/bin/php -f /var/www/detect.php 6 > /dev/null 2>&1 &");
detect.php does not start. I don't have any errors.
If to remove "&":
exec("/usr/bin/php -f /var/www/detect.php 6 > /dev/null 2>&1 ");
detect.php starts successfully.
From shell bash with "&" :
sudo -u www-data /usr/bin/php -f /var/www/detect.php 6 > /dev/null 2>&1 &
Script detect.php starts successfully.
try this and make sure your php path are correct
$dir=dirname(__FILE__);
$file_name="detect.php";
$php_path="/usr/bin/php";
$args = array(6);
$command1="cd $dir";
$command2="$php_path $file_name ".implode(" ",$args) ." > /dev/null 2>/dev/null &";
$final_command=$command1."; ".$command2;
shell_exec($final_command);
I think there are tons of similar posts but I haven't yet found a solution after searching around.
Basically, I'm trying to run two scripts in the background. When I run them in the commandline, I see after calling my first script:
/usr/bin/nohup php script.php > nohupoutput.log & echo $!
I've tried ...script.php > /dev/null & with the same result. I get:
/usr/bin/nohup: ignoring input and redirecting stderr to stdout
which I ignore and run the second one. I noticed that it seemed to be hanging there, and pressing Enter brought me back to machine:~folder>
/usr/bin/nohup php script2.php > nohupoutput.log & echo $!
Both scripts work. I tried to then convert this to a shell_exec command and nothing seems to work. I suspect that the ignoring input bit is causing difficulties, but I'm not sure. Regardless, the following does not work. It just hangs in the browser:
$output = shell_exec('/usr/bin/nohup php script.php > /dev/null &');
$output = shell_exec('/usr/bin/nohup php script2.php > /dev/null &');
Try:
$output = shell_exec('/usr/bin/nohup php script.php >/dev/null 2>&1 &');
Or:
exec('/usr/bin/nohup php script.php >/dev/null 2>&1 &');
This shoul work:
shell_exec('nohup /usr/bin/php path/to/script.php > output.txt &');
<?php
function execInBackground($cmd) {
if (substr(php_uname(), 0, 7) == "Windows"){
pclose(popen("start /B ". $cmd, "r"));
}
else {
exec($cmd . " > /dev/null &");
}
}
// take note: to get your PHP_PATH, try looking at your phpinfo :)
echo execInBackground("/usr/local/php53/bin/php 'example2.php'");
?>
First put your php command in a shell file script, e.g. myscript.sh:
#!/bin/bash
# myscript.sh file
php script.php
Run nohup with myscript.sh:
sudo nohup ./myscript.sh &
Verify with ps:
ps aux | grep myscript.sh
I have a QNAP box, that runs a flavor of linux and I am having problems getting the PID of a process using a php script. What I have so far:
$command = "PATH=$PATH:/share/MD0_DATA/.qpkg/Optware/bin: nohup /opt/bin/plowdown -o /share/MD0_DATA/Qdownload/plowshare http://www.megaupload.com/?d=m7duotr1 2> /share/MD0_DATA/Qdownload/plowshare/outputeeds.txt > /dev/null &";
exec($command, $out);
$result = $out[0];
echo $result;
If I run the command through PUTTY, I get:
[~] # nohup /opt/bin/plowdown -o /share/MD0_DATA/Qdownload/plowshare http://www.megaupload.com/?d=m7duotr1 2> /share/MD0_DATA/Qdownload/plowshare/outputteeds.txt > /dev/null &
22526
What am I doing wrong?
Thanks,
Cristian.
The shell does not normally print the PID of a process it starts in background, unless it's interactive. Otherwise, you would get tons of output during bootup just from the PIDs of all the processes that get started.
So you need to make the shell print the PID. Do
exec("(PATH=$PATH:/share/MD0_DATA/.qpkg/Optware/bin: " .
"nohup /opt/bin/plowdown -o /share/MD0_DATA/Qdownload/plowshare " .
"http://www.megaupload.com/?d=m7duotr1 2> " .
"/share/MD0_DATA/Qdownload/plowshare/outputeeds.txt > /dev/null &);" .
"echo $$;", $out);
http://nl2.php.net/manual/en/function.getmypid.php