Ok so I have a operating system Ubuntu. I have lampp. Now I wanna execute some command in the background which is going to take atleast 10-15 minutes to execute. I want to execute this command from PHP script from web interface not cli.
First Instance:
When I do this , the php script is successfully able to run the command in the background:
command1 &> /dev/null &
Second Instance:
But when I do this:
command1 &> /dev/null && command2 &
,
Then the command does not run in background, the php script pauses until this command executes. I want the command2 to execute after command1 is completed so that I (or my php script) can know that command1 has been executed. But it should be in background else my php script doesn't execute on time.
When I do the second instance from command line, it is able to run in background, but when I do it from php script then it is unable to run in background.
I am using the exec function of php to execute those commands.
<?php
exec('command1 &> /dev/null && command2 &',$out,$ret);
?>
Any help would be appreciated.
Try this:
<?php
exec('(command1 && command2) >/dev/null &',$out,$ret);
What it's doing is launching your commands in a subshell so that command1 runs first and then command2 only runs after command1 completes successfully, then redirects all the output to dev/null and runs the whole thing in the background.
If you want to run command2 regardless of the exit code of command1 use ; instead of &&.
The computer is doing what you're instructing it to do. The && list operator tells the shell to only run the second command if the first command completes successfully. Instead, you should run two independent commands; if there really is a dependency between the two commands, then you may need to reconsider your approach.
Related
I'm trying to run my server from PHP script as a background process, but it's hanging the PHP script anyway. I call it like this:
$exec_result = exec('./myapp option1 option2 &> /dev/null &');
I tried things from PHP hanging while exec() bash script like adding "set -m && " or "shopt -u checkjobs && " but that doesn't help. I also tried to call in exec() my C++ utility that runs command in background (basically just calls std::system with " &"), but that didn't help either. Using "nohup" doesn't change anything. Also, the problem is not in my server because same thing happens when I call "sleep" command.
Calling exactly the same command from bash runs process in background as expected. Honestly I'm so confused and frustrated. What am I doing wrong? Maybe PHP needs some kind of permissions to run a background task? I'm kinda new to Linux.
I'm doing it all from Debian 10 and PHP 7.3 if it matters.
I've managed to fix it, but I have no idea why the new solution works while the old one doesn't. Maybe it has something to do with exec() build-it parser? Both lines work identically in bash so I'm blaming PHP on this.
So, I've replaced
$exec_result = exec('./myapp option1 option2 &> /dev/null &');
with
$exec_result = exec('./myapp option1 option2 > /dev/null 2>&1 &');
and that did it. I've checked it back and forth multiple times and the second line works consistently while the first one fails every time.
When executing multiple scripts within PHP using the exec command; are each script ran one at a time as in one after the other or are they ran simultaneously?
exec('/usr/bin/php -q process-duplicates.php');
exec('/usr/bin/php -q process-images.php');
exec('/usr/bin/php -q process-sitemaps.php');
Just want to make sure they are one after the other before attempting to rewrite my crontabs.
Sure, the only way to run at background is adding & to the command line arguments, which would put that exec()'d process into the background:
exec("php test.php &");
So you are right, they run one after the other.
NOTE: In your case you shouldn't use & as it will force to run all the scripts simultaneously.
exec waits for the script to return, see php.net
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.
But as a devops, please please please do not run your cron jobs like this! Create entries in the crontab for each, or put them in a shell script and have cron run the script.
I have a simple question, i searched and I couldn't find a solution.
I have a simple shell script that run a small php code every 2 seconds, I wrote it and save as a file:
$ cat every-2-seconds.sh
#!/bin/bash
while true
do
php /home/account/domains/domain.co.il/public_html/my-php-script.php
sleep 2
done
Now, i need that this script will always run on background, but I also need that it will run on startup, Just like a service, it should always run in background, and I never want to start it manually (of course, if something happen and it will stop, i should be able to start it manually)
I heard about nohup, but its not a service right? and I can start it on startup.. :(
Can you help me on this??
You can make your script run with this line of code (assuming you are in the directory with your script)
nohup every-2-seconds.sh &
The & will run this as a background task and nohup will keep the process running even after you've disconnected from your session.
To handle starting it on reboot you need to add this command to your crontab
crontab -e
#reboot /path/to/every-2-seconds.sh > /dev/null
In the crontab you need to specify the full path. You can change /dev/null to the file you want output to go to (assuming you want the output)
I have several cron jobs that run automatically, and I was requested to add a button that says 'run now' in the browser... Is this possible? Some of these cron jobs need to be executed from command line as they take around 15 minutes... Is it possible to execute them from the browser, not as a normal php function but somehow trigger an external php from the browser?
You're looking for the exec() function.
If it's a 15 minute task, you have to redirect its output and execute in in the background. Normally, exec() waits for the command to finish.
Example: exec("somecommand > /dev/null 2>/dev/null &");
I am trying to manage a queue of files waiting to be processed by ffmpeg. A page is run using CRON that runs through a database of files waiting to be processed. The page then builds the commands and sends them to the command line using exec().
However, when the PHP page is run from the command line or CRON, it runs the exec() OK, but does not return to the PHP page to continue updating the database and other functions.
Example:
<?php
$cmd = "ffmpeg inpupt.mpg output.m4v";
exec($cmd . ' 2>&1', $output, $return);
//Page continues...but not executed
$update = mysql_query("UPDATE.....");
?>
When this page is run from the command line, the command is run using exec() but then the rest of the page is not executed. I think the problem may be that I am running a command using exec() in a page run from the command line.
Is it possible to run a PHP page in full from the command line which includes exec()?
Or is there a better way of doing this?
Thank you.
I wrote an article about Running a Background Process from PHP on Linux some time ago:
<?php system( 'sh test.sh >/dev/null &' ); ?>
Notice the & operator at the end. This starts a process that returns control to the shell immediately AND CONTINUES TO RUN in the background.
More examples:
<!--
saving standard output to a file
very important when your process runs in background
as this is the only way the process can error/success
-->
<?php system( 'sh test.sh >test-out.txt &' ); ?>
<!--
saving standard output and standard error to files
same as above, most programs log errors to standard error hence its better to capture both
-->
<?php system( 'sh test.sh >test-out.txt 2>test-err.txt &' ); ?>
Have you tried using CURL instead?
Unsure but probably thats due to the shell constraints of cron processes if it works as a web page then use it as a web page, setup a cron job that calls wget wherever_your_page_is and it will be called via your web server and should mimic your tests.