【问题标题】:(PHP) Live output proc_open(PHP) 实时输出 proc_open
【发布时间】:2018-12-04 21:11:28
【问题描述】:

我已经尝试了很多次,通过使用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);

}

提前致谢

【问题讨论】:

    标签: php exec proc-open passthru


    【解决方案1】:

    我认为问题在于您等待输入的循环。 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);
    }
    

    【讨论】:

    • 第一个代码仍然不打印其他命令的完整输出,最后一个打印完整输出并且工作完美,我的目标是让它没有问题的实时输出。谢谢 Miken32 先生
    猜你喜欢
    • 2022-08-03
    • 1970-01-01
    • 2018-01-12
    • 1970-01-01
    • 1970-01-01
    • 2011-01-13
    • 2023-03-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多