当我从PHP运行exec
时:
$result = exec('command');
此结果将存储在$result
中。但在我目前的情况下,我的命令可能需要几分钟,并在运行时输出结果。有没有办法在运行时获得输出?我知道passthru
方法会将结果输出为浏览器,但实际上我直接想要它。
答案 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);