(PHP) Живой вывод proc_open - PullRequest
0 голосов
/ 05 декабря 2018

я много раз пытался с помощью 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 голосов
/ 05 декабря 2018

Я считаю, что проблема в том, что у вас есть цикл ожидания ввода.fgets вернет false только в том случае, если встретится с EOF.В противном случае он возвращает строку, которую прочитал;поскольку перевод строки включен, он не возвращает ничего, что может быть приведено к ложному.Вместо этого вы можете использовать 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);
}
...