(PHP)实时输出proc_open

时间:2018-12-04 21:11:28

标签: php exec proc-open passthru

我已经尝试使用flush()使脚本同步运行很多次,该脚本仅打印第一个命令“ gcloud compute ssh yellow”和“ 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 "\n\n## ==>> ";
        echo $f;
    }
    fclose($pipes[2]);
    proc_close($process);

}

预先感谢

1 个答案:

答案 0 :(得分:0)

我相信问题是您等待输入的循环。 fgets仅在遇到EOF时返回false。否则,它返回读取的行;因为包含了换行符,所以它不会返回任何可以类型转换为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);
}
相关问题