(PHP)实时输出proc_open



我已经尝试过多次使用flush()使脚本同步工作,脚本只打印第一个命令"gcloud compute ssh yellow"one_answers"ls-la"的数据,我希望使脚本在每个执行的fputs()上打印输出。

<?php
$descr = array( 0 => array('pipe','r',),1 => array('pipe','w',),2 => array('pipe','w',),);
$pipes = array();
$process = proc_open("gcloud compute ssh yellow", $descr, $pipes);
if (is_resource($process)) {
sleep(2);
$commands = ["ls -la", "cd /home", "ls", "sudo ifconfig", "ls -l"];     
foreach ($commands as $command) {    
fputs($pipes[0], $command . " n");
while ($f = fgets($pipes[1])) {
echo $f;
}
}
fclose($pipes[0]);  
fclose($pipes[1]);
while ($f = fgets($pipes[2])) {
echo "nn## ==>> ";
echo $f;
}
fclose($pipes[2]);
proc_close($process);
}

提前感谢

我认为问题出在等待输入的循环上。fgets只有在遇到EOF时才会返回false。否则,它将返回读取的行;因为linefeed包含在内,所以它不会返回任何可以被类型转换为false的内容。您可以改用stream_get_line(),它不会返回EOL字符。请注意,这仍然需要您的命令在其输出后返回一个空行,这样它就可以计算为false并中断while循环。

<?php
$prog     = "gcloud compute ssh yellow";
$commands = ["ls -la", "cd /home", "ls", "sudo ifconfig", "ls -l"];
$descr    = [0 => ['pipe','r'], 1 => ['pipe','w'], 2 =>['pipe','w']];
$pipes    = [];
$process  = proc_open($prog, $descr, $pipes);
if (is_resource($process)) {
sleep(2);
foreach ($commands as $command) {
fputs($pipes[0], $command . PHP_EOL);
while ($f = stream_get_line($pipes[1], 256)) {
echo $f . PHP_EOL;
}
}
fclose($pipes[0]);
fclose($pipes[1]);
fclose($pipes[2]);
proc_close($process);
}

另一种选择是在循环外收集输出,尽管如果需要知道什么输出来自哪个命令,则需要解析输出。

<?php
$prog     = "gcloud compute ssh yellow";
$commands = ["ls -la", "cd /home", "ls", "sudo ifconfig", "ls -l"];
$descr    = [0 => ['pipe','r'], 1 => ['pipe','w'], 2 =>['pipe','w']];
$pipes    = [];
$process  = proc_open($prog, $descr, $pipes);
if (is_resource($process)) {
sleep(2);
foreach ($commands as $command) {
fputs($pipes[0], $command . PHP_EOL);
}
fclose($pipes[0]);
$return = stream_get_contents($pipes[1]);
$errors = stream_get_contents($pipes[2]);
fclose($pipes[1]);
fclose($pipes[2]);
proc_close($process);
}

最新更新