在命令仍在运行时从php exec()获取结果?

时间:2011-10-09 11:51:08

标签: php exec

当我从PHP运行exec时:

$result = exec('command');

此结果将存储在$result中。但在我目前的情况下,我的命令可能需要几分钟,并在运行时输出结果。有没有办法在运行时获得输出?我知道passthru方法会将结果输出为浏览器,但实际上我直接想要它。

5 个答案:

答案 0 :(得分:5)

你应该看看proc_open

在使输出流非阻塞(使用stream_set_blocking)之后,您可以随时从中读取,而不会阻止您的PHP代码。

CNC中 如果你使用

$result = exec('command > /path/to/file &');

它将在后台运行,您可以读取/ path / to / file

中的输出

答案 1 :(得分:4)

也许不是最好的方法(但对我有用):

<?php

$cmd = "ping 127.0.0.1 -c 5"; //example command

$descriptorspec = array(
    0 => array("pipe", "r"), 
    1 => array("pipe", "w"), 
    2 => array("pipe", "a")
);

$pipes = array();

$process = proc_open($cmd, $descriptorspec, $pipes, null, null);

echo "Start process:\n";

$str = "";

if(is_resource($process)) {
    do {
        $curStr = fgets($pipes[1]);  //will wait for a end of line
        echo $curStr;
        $str .= $curStr;

        $arr = proc_get_status($process);

    }while($arr['running']);
}else{
    echo "Unable to start process\n";
}

fclose($pipes[0]);
fclose($pipes[1]);
fclose($pipes[2]);
proc_close($process);

echo "\n\n\nDone\n";

echo "Result is:\n----\n".$str."\n----\n";

?>

答案 2 :(得分:3)

指定第二个参数

exec('command', $result);
  

如果输出参数存在,那么指定的数组将是   填充了命令的每一行输出。尾随   空格,例如\ n,不包含在此数组中。请注意,如果   数组已经包含一些元素,exec()会附加到   数组的结尾。如果您不希望该函数追加元素,   在将数组传递给exec()之前调用数组上的unset()。

答案 3 :(得分:0)

使用passthru()结合output buffering可能会实现您的需求。但不确定。

答案 4 :(得分:0)

对于任何可能有帮助的人,我已经使用了Eddie的答案并根据我的目的对其进行了修改(输出MySQL转储文件而不会淹没服务器的RAM)

$dumpCommand = "mysqldump --skip-lock-tables -u $dbuser -p$dbpasswd $dbname";
$dumpFileName = 'backup_'.$dbname.'-'.date('Ymd-Hi').'.sql';

$descriptorSpec = array(
    0 => array("pipe", "r"), 
    1 => array("pipe", "w"), 
    2 => array("pipe", "a")
);

$pipes = array();

$process = proc_open($dumpCommand, $descriptorSpec, $pipes, null, null);

if(!is_resource($process)) {
    die('Unable to start process');
}

header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.$dumpFileName.'"');

do {
    echo fgets($pipes[1]); // Will wait for EOL
    $arrStatus = proc_get_status($process);
} while($arrStatus['running']);

fclose($pipes[0]);
fclose($pipes[1]);
fclose($pipes[2]);
proc_close($process);