I am trying to execute a command with exec() and redirecting stdout and stderr to a file.
exec("nohup python main.py -i 1 > /var/scripts/logs/1_out.log 2>&1 &");
It will create the file but it will not print anything to it.
If I run the command in a terminal everything outputs without a problem.
Got it working. Python does its own output buffering which kept it from writing to the file. Running it with the -u option disables this. Final code looks like this:
exec("nohup python -u main.py -i 1 > /var/scripts/logs/1_out.log 2>&1 </dev/null &");
Thanks.
Related
I am attempting to launch sar and have it run forever via a php script. But for whatever reason it never actually launches. I have tried the following:
exec('sar -u 1 > /home/foo/foo.txt &');
exec('sar -o /home/foo/foo -u 1 > /dev/null 2>&1 &');
However it never launches sar. If I just use:
exec('sar -u 1')
It works but it just hangs the php script. My understanding that 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.
I will assume your running this on a *nix platform. To get php to run something in the background and not wait for the process to finish I would recommend 2 things: First use nohup and also redirect the output of the command to /dev/null (trash).
Example:
<?php
exec('nohup sar -u 1 > /dev/null 2>/dev/null &');
nohup means we do not send the "hang up" signal (which kills the process) when the terminal running the command closes.
> /dev/null 2>/dev/null & redirects the "normal" and "error" outputs to the blackhole /dev/null location. This allows PHP to not have to wait for the outputs of the command being called.
On another note, if you are using PHP just to call a shell command, you may want to consider other options like Ubuntu's Upstart with no PHP component--if you are using Ubuntu that is.
I have a long running PHP script that i want to be executed in background on server after a user action. and the user should be redirected to other page while command should be running in background.
Below is the code
$command = exec('php -q /mylongrunningscript.php');
header("Location: /main.php?action=welcome");
The above script is running fine, but page does not redirected until $command = exec('php -q /mylongrunningscript.php'); is executed.
I want that user should be immediately redirected to the welcome page.
Is there any other way to achieve this task.
The other idea is that that $command = exec('php -q /mylongrunningscript.php'); should be executed on welcome page, but welcome page HTML is shown after the command has executed. command takes about 5,6 minutes and this time page does not redirects.
I am On Cent os Linux with PHP 5.3
Can you try this instead:
$result = shell_exec('php -q /mylongrunningscript.php > /dev/null 2>&1 &');
PS: Note that this is redirecting stdout and stderr to /dev/null If you want to capture output then use:
$result = shell_exec('php -q /mylongrunningscript.php > /tmp/script.our 2>&1 &');
Alternatively use this PHP function to run any Unix command in background:
//Run linux command in background and return the PID created by the OS
function run_in_background($Command, $Priority = 0) {
if($Priority)
$PID = shell_exec("nohup nice -n $Priority $Command > /dev/null & echo $!");
else
$PID = shell_exec("nohup $Command > /dev/null & echo $!");
return($PID);
}
Courtesy: A comment posted on http://php.net/manual/en/function.shell-exec.php
As noted in the exec() manual page of PHP:
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.
So let's do that, using 2>&1 (basically 2 is stderr and 1 is stdout, so what this means is "redirect all stderr messages to stdout"):
shell_exec('php -q /mylongrunningscript.php 2>&1');
or if you want to know what it outputs:
shell_exec('php -q /mylongrunningscript.php 2>&1 > output.log');
Send the script output to /dev/null and the exec function will return immediately
$command = exec('php -q /mylongrunningscript.php > /dev/null 2>&1');
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 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
Related: see here
I've got this command:
exec("(wget -O http://domain/file.zip && mysql -u user -ppassword database -e \"UPDATE \\`table\\` SET \\`status\\` = 'live' WHERE \\`id\\` = '1234'\") & echo \$!");
The above command works fine, however PHP waits for the video to finish downloading before going on to the next download. The following line, however, sends the download to the background, which is what I'm trying to achieve from the previous line.
exec("wget -O http://domain/file.zip &>/dev/null & echo \$!");
How do I go about changing the first line above to send the download to the background?
You have to make you use & to send the the process to the background and that you redirect all output. So you need to add
> /dev/null 2>&1 &
at the end of your command. So you should end up with something like this:
exec("(wget -O http://domain/file.zip && mysql -u user -ppassword database -e \"UPDATE \\`table\\` SET \\`status\\` = 'live' WHERE \\`id\\` = '1234'\") echo \$! > /dev/null 2>&1 &");
[Edit]
To make thing simpler, you can also move the wget and the update to another php file that you would call with exec. So you would end up with only
exec("php NewFile.php > /dev/null 2>&1 &");