I'm calling exec to run scripts in backgroud using php exec() and wget. But everytime I call this it's creating a file with url parameters in my server. I tried to disable output and tried to store it to a specific file also. Both failed.
here is my code
function execInBackground($cmd)
{
$cmd = escapeshellcmd($cmd);
exec($cmd . " > /dev/null &");
}
And I'm calling it like below
execInBackground('wget -q http://example.com/d/do-processing?process=501&res=201');
So now it will create a file named
do-processing?process=501&res=201
in my server. Can you guys please mention is there anything I missed while doing this.
I want to call that url in background without saving any output. In worst case I need to store the output of each call to a specific file instead of creating multiple files.
exec($cmd . " > process.out 2> process.err < /dev/null &");
I tried like above code and didn't worked.
The solution is to use wgets' -o or --output-file argument like this:
exec('wget -q -o /dev/null http://example.com/d/do-processing?process=501&res=201 &');
Then no output file will be created.
Related
I am struggling with getting a php file to run in the background with PHP's exec(). As a first test, I tried :
exec("ls -l > logfile.txt 2> errfile.txt &");
That works fine. logfile.txt gets filled with a directory listing.
Per instructions in the php documentation, since the exec kicks off a process that runs in the background, standard out (and standard error) are redirected to a file.
Now, I try
exec("/usr/bin/php -f /path/to/my.php > logfile.txt 2> errorfile.txt &");
It appears nothing happens.
Here are test files that I'm trying:
alpha.php
<?php
$version="a";
// Go do something we do not need to wait for.
exec("/usr/bin/php -f /path/to/beta.php > logfile.txt 2> errorfile.txt &");
?>
<html>
<head><title>Test</title></head>
<body>
<p>This is Alpha version <?php echo $version; ?></p>
</body>
</html>
beta.php
<?php
if (!($fp = fopen('/home/johnst12/public_html/workshops/admin/betadata.txt', 'w'))) { exit;}
fprintf($fp, "Proof that Beta executed.");
fclose($fp);
?>
If I run beta.php directly, it works fine. Betadata.txt gets the message.
If I run alpha.php to launch beta.php, betadata.txt is not created. logfile.txt and errorfile.txt remain empty (expected).
I am sure that the path to php, and the path to my php file are correct.
Googling for clarification has not been fruitful. A couple of common themes seem to be (a) running out of resources? (b) lack of permission on the target php file? Out of resources seems unlikely. The permission on the script is global read 644 (rw-r--r--). I tried adding execute (755) just in case it would help. It made no difference.
PHP version 5.3.21
Linux/Apache system.
safe_mode Off
What am I missing? Thanks.
First of all : Have you verified that /usr/bin/php is the correct path to PHP?
Php doesn't like running like that. Something to do with stdin. Try with nohup:
exec("nohup /usr/bin/php -f /path/to/beta.php > logfile.txt 2> errorfile.txt &");
With -f anything else that looks like a flag will go to PHP, so if you wanted to pass a "-x" option to your script then you'd have to
/usr/bin/php -f /path/to/beta.php -- -x
Without, options before the filename go to PHP and after go to the script.
/usr/bin/php /path/to/beta.php -x
I assume you've already looked at the two files in case they have output or errors?
A few other things to check:
Delete the two files. Are they recreated each time this code runs?
exec("nohup /usr/bin/php -v > logfile.txt &");
should output version information to that log file.
exec("/usr/bin/php -f /path/to/beta.php > logfile.txt 2> errorfile.txt");
should run the script properly (but not in the background).
Is there any way to execute a makefile in a php file? I have tried:
exec('cmd /c "C:\\Program Files\\Microsoft Visual Studio\\VC98\\Bin\\nmake.exe" -f E:\\dev\\temp.mak > process.out 2> process.err < /dev/null &');
But I donot think this way makefile gets to run.
Why not doing :
$make = escapeshellarg("C:\Program Files\Microsoft Visual Studio\VC98\Bin\nmake.exe");
$path = escapeshellarg("E:\dev\temp.mak");
exec("start /B {$make} -f {$path} > process.out 2> process.err");
start /B will execute your program in background
> process.out will redirect standard output to "process.out" file
2> process.err will redirect error output to "process.err" file
In this example, process.out and process.err will be erased each time make is run. To avoid this behaviour, just replace > symbols by >>, and files will be appended.
Try different methods of doing this, Create a windows batch file in the same place as your PHP directory;
cd C:\"Program Files"\"Microsoft Visual Studio"\VC98\Bin
nmake.exe -f E:\dev\temp.mak > process.out 2> process.err
*Incorporating Zids Comment into this: *
How would you execute it from the command line, if you were not using PHP? – rid
If the above method doesn't work. Search online for usage of that exe by running it from windows command prompt, then change the .batch file accordingly.*
Save this as a .batch file, then from your PHP try running
exec ("filename.bat", $output);
then
View the output performed by the exec command in a simple foreach loop
foreach ($output AS $OutputStr)
{
echo $OutputStr."<br>";
}
There should be some output, from the output I would work with that.
I have the following exec() command with an & sign at the end so the script runs in the background. However the script is not running in the background. It's timing out in the browser after exactly 5.6 minutes. Also if i close the browser the script doesn't keep running.
exec("/usr/local/bin/php -q /home/user/somefile.php &")
If I run the script via the command line, it does not time out. My question is how do i prevent timeout. How do i run the script in the background using exec so it's not browser dependent. What am i doing wrong and what should i look at.
exec() function handle outputs from your executed program, so I suggest you to redirect outputs to /dev/null (a virtual writable file, that automatically loose every data you write in).
Try to run :
exec("/usr/local/bin/php -q /home/gooffers/somefile.php > /dev/null 2>&1 &");
Note : 2>&1 redirects error output to standard output, and > /dev/null redirects standard output to that virtual file.
If you have still difficulties, you can create a script that just execute other scripts. exec() follows a process when it is doing a task, but releases when the task is finished. if the executed script just executes another one, the task is very quick and exec is released the same way.
Let's see an implementation. Create a exec.php that contains :
<?php
if (count($argv) == 1)
{
die('You must give a script to exec...');
}
array_shift($argv);
$cmd = '/usr/local/bin/php -q';
foreach ($argv as $arg)
{
$cmd .= " " . escapeshellarg($arg);
}
exec("{$cmd} > /dev/null 2>&1 &");
?>
Now, run the following command :
exec("/usr/local/bin/php -q exec.php /home/gooffers/somefile.php > /dev/null 2>&1 &");
If you have arguments, you can give them too :
exec("/usr/local/bin/php -q exec.php /home/gooffers/somefile.php x y z > /dev/null 2>&1 &");
You'll need to use shell_exec() instead:
shell_exec("/usr/local/bin/php -q /home/gooffers/somefile.php &");
That being said, if you have shell access, why don't you install this as a cronjob? I'm not sure why a PHP script is invoking another to run like this.
I'm calling this in my php script:
exec("gutschein.php >/dev/null 2>&1 &");
Calling the script (generates a pdf and sends it away by e-mail) works, but the process is not running in the background (I checked it out with a sleep statement inside gutschein.php). The browser is hanging until execution of gutschein.php is finished.
I also checked out the following:
exec("/usr/bin/php gutschein.php >/dev/null 2>&1 &");
or
shell_exec("/usr/bin/php gutschein.php >/dev/null 2>&1 &");
It doesn't change anything. The script is actually running on a linux server. Has anybody an idea what I'm doing wrong?
Try system and/or passthru. I've had issues with exec before because it halts trying to fill the return array with data until the process has finished.
These will both echo raw output so even if they work you may need to handle that with a discarded output buffer.
/**
* #author Micheal Mouner
* #param String $commandJob
* #return Integer $pid
*/
public function PsExec($commandJob)
{
$command = $commandJob . ' > /dev/null 2>&1 & echo $!';
exec($command, $op);
$pid = (int) $op[0];
if ($pid != "")
return $pid;
return false;
}
This worked for me .. check it
also, return processId of the background process
All output must be redirected, else the script will hang as long as gutschein.php executes. Try
exec('/usr/bin/php gutschein.php &> /dev/null &');
Can you try one of the following 2 commands to run background jobs from PHP:
$out = shell_exec('nohup /usr/bin/php /path/to/gutschein.php >/dev/null 2>&1 &');
OR
$pid = pclose(popen('/usr/bin/php gutschein.php', 'r'));
It will execute the command in background and returns you the PID, which you can check using condition $pid > 0 to ensure it has worked.
You can use screen: screen -d -m /usr/bin/php gutschein.php
Here is screen's manual if you need more info on options.
Please see my experience at HERE.
The way I try and works for me -
php -q /path/to/my/test/script/cli_test.php argument1 < /dev/null &
In PHP, it is like
exec('php -q /path/to/my/test/script/cli_test.php argument1 < /dev/null &')
The browser is might waiting for a response, so let your script produce any output and terminate the "main process". a simple
die('ok');
should do the job.
btw, forking a new process by calling exec is might not the best solution since the new process isn't a real child process - means you can't control it. you might consider using pcntl (http://php.net/manual/de/book.pcntl.php) for this purpose. but stand clear, this extension has also his pitfalls, especially in the context of a webserver.
How to execute a php script from another ?
I want to execute 3 php scripts from my php file without waiting for the 3 scripts to finish. In other words, the 3 php files need to be executed all at once (parallel) instead of one-by-one (sequentiell).
The 3 scripts are in the same folder of my main php file (script).
If you do not want to wait for them to finish, run them with either
exec('php script.php &> /dev/null &');
shell_exec('php script.php &> /dev/null &');
system('php script.php &> /dev/null &');
`php script.php &> /dev/null &`
Any of those should accomplish the job, depending on your PHPs configuration. Although they are different functions, their behaviour should be similar since all output is being redirected to /dev/null and the proccess is immediately detached.
I use the first solution in a production environment where a client launches a bash SMSs sending script which can take up to 10 minutes to finish, it has never failed.
More info in: http://php.net/exec · http://php.net/shell_exec · http://php.net/system
how about using exec("php yourscript.php")
do consider using queuing system to store your php script names and worker to fetch data from queue and do the execution e.g. beanstalkd
You need to run them as detached jobs, and it is not really easy - or portable. The usual solution is to use nohup or exec the scripts with stdout and stderr redirected to /dev/null (or NUL in Windows), but this often has issues.
If possible, make the three scripts available as scripts on the web server, and access them through asynchronous cURL functions. This has also the advantage of being able to test the scripts through the browser, and supplying you the scripts output.
Other ways include using popen(), or if under Linux, the at or batch utility.
taken from http://board.phpbuilder.com/showthread.php?10351142-How-can-I-exec%28%29-in-a-non-blocking-fashion:
In order to execute a command have 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 &"');
For windows http://www.php.net/manual/en/function.exec.php:
function execInBackground($path, $exe, $args = "") {
global $conf;
if (file_exists($path . $exe)) {
chdir($path);
if (substr(php_uname(), 0, 7) == "Windows"){
pclose(popen("start \"bla\" \"" . $exe . "\" " . escapeshellarg($args), "r"));
} else {
exec("./" . $exe . " " . escapeshellarg($args) . " > /dev/null &");
}
}
To the shell_exec, add the '/B' parameter, this allows you to run several executables at once.
See my answer at this question: PHP on a windows machine; Start process in background
It's the same.
shell_exec('start /B "C:\Path\to\program.exe"); /B parameter is key
here. I tried to find the topic for you again, but I can't seem to
find it anymore. This works for me.
I hope this solves the problem for you.