Running exec("nohup curl ...") in PHP and redirecting stderr

147 Views Asked by At

I have a piece of php code that executes multiple curl request using the exec() function. The goal is to download a lot of files simultaneously, at the same keep track of the PIDs as well as the progress. A simplified version is like this:

<?php
// some code here
unset($pid);
for($i=1;$i<=100;$i++) {
    exec("nohup curl '".$url[$i]."' -o output-".$i.".dat > log/".$i.".log & echo $!",$pid[$i]);
}
// some code here
?>

where

$url[] is an array containing a lot of urls

$pid[] is an array containing the PID of the curl process. I need this to check if the process is finished, then perform other tasks.

output-i.dat is the downloaded files

log/i.log is a text file containing the process generated by curl in cli. I need this to make sure the file is 100% downloaded and connection is not lost mid-way

The reason I need to use nohup is to obtain the PID, without nohup I cannot get the PID from echo $!

This script works and achieved what I need however when I run the code in cli php download.php the screen will be flooded with

nohup: redirecting stderr to stdout
nohup: redirecting stderr to stdout
......
nohup: redirecting stderr to stdout
nohup: redirecting stderr to stdout

I want to know if there is anyway to pipe this output to /dev/null

I tried to include > /dev/null 2>&1 in the php like this

exec("nohup curl '".$url[$i]."' -o output-".$i.".dat > log/".$i.".log > /dev/null 2>&1 & echo $!",$pid[$i]);

but it does not work. Neither will this work:

exec("nohup curl '".$url[$i]."' -o output-".$i.".dat > log/".$i.".log 2>/dev/null & echo $!",$pid[$i]);

I was hoping there is a quiet switch for nohup but it does not seem to have one.

1

There are 1 best solutions below

3
Pruss On

This gets the PID, output and hides the nohup: redirecting stderr to stdout message:


$o = array();
$output = exec("nohup curl -h 2> /dev/null & echo $!", $o);

$pid = $o[0];

This gets the PID, writes the status to log file and hides the nohup message:


$o = array();
exec("nohup curl -h > log.log 2> /dev/null & echo $!", $o);

$pid = $o[0];

This gets the PID, writes the output to file, the status to log and hides the nohup message:


$o = array();
exec("nohup curl example.com -o output --stderr log.log 2> /dev/null & echo $!", $o);

$pid = $o[0];

And finally, to integrate it with your code:

$i = 0;
$url = array('example.com');
$pid = array();

$o = array();
exec("nohup curl '$url[$i]' -o output-$i.dat --stderr log-$i.log 2> /dev/null & echo $!", $o);

$pid[$i] = $o[0];