PHP чтение shell_exec в прямом эфире
Я просто экспериментирую с PHP и shell_exec
на моем Linux-сервере. Это действительно классная функция для использования, и я до сих пор наслаждаюсь ею. Есть ли способ просмотра живого вывода, который выполняется во время выполнения команды?
Например, если был запущен ping stackoverflow.com
, когда он пинговал целевой адрес, каждый раз, когда он пингует, показывайте результаты с помощью PHP? Возможно ли это?
Мне бы очень хотелось увидеть текущее обновление буфера при его запуске. Возможно, это невозможно, но это было бы неплохо.
Это код, который я пытаюсь, и каждый раз, когда я его пробовал, он всегда отображает результаты после завершения команды.
<?php
$cmd = 'ping -c 10 127.0.0.1';
$output = shell_exec($cmd);
echo "<pre>$output</pre>";
?>
Я попытался поместить часть echo
в цикл, но все равно не повезло. У кого-нибудь есть предложения по поводу того, чтобы показать живое выступление на экране, а не ждать завершения команды?
Я пробовал exec
, shell_exec
, system
и passthru
. Каждый из них отображает контент после его завершения. Если я не использую неправильный синтаксис, или я неправильно настрою цикл.
Ответы
Ответ 1
Чтобы прочитать результат процесса, popen()
- это путь. Ваш script будет работать параллельно с программой, и вы можете взаимодействовать с ним, читая и записывая его вывод/ввод, как если бы это был файл.
Но если вы просто хотите сбросить результат прямо к пользователю, вы можете вырезать дерьмо и использовать passthru()
:
echo '<pre>';
passthru($cmd);
echo '</pre>';
Теперь, если вы хотите отображать вывод во время выполнения программы, вы можете сделать это:
while (@ ob_end_flush()); // end all output buffers if any
$proc = popen($cmd, 'r');
echo '<pre>';
while (!feof($proc))
{
echo fread($proc, 4096);
@ flush();
}
echo '</pre>';
Этот код должен запускать команду и нажимать вывод прямо на конечного пользователя во время выполнения.
Ответ 2
Прежде всего, спасибо Havenard за ваш фрагмент - это очень помогло!
Немного модифицированная версия кода Havenard, которую я нашел полезным.
<?php
/**
* Execute the given command by displaying console output live to the user.
* @param string cmd : command to be executed
* @return array exit_status : exit status of the executed command
* output : console output of the executed command
*/
function liveExecuteCommand($cmd)
{
while (@ ob_end_flush()); // end all output buffers if any
$proc = popen("$cmd 2>&1 ; echo Exit status : $?", 'r');
$live_output = "";
$complete_output = "";
while (!feof($proc))
{
$live_output = fread($proc, 4096);
$complete_output = $complete_output . $live_output;
echo "$live_output";
@ flush();
}
pclose($proc);
// get exit status
preg_match('/[0-9]+$/', $complete_output, $matches);
// return exit status and intended output
return array (
'exit_status' => intval($matches[0]),
'output' => str_replace("Exit status : " . $matches[0], '', $complete_output)
);
}
?>
Пример использования:
$result = liveExecuteCommand('ls -la');
if($result['exit_status'] === 0){
// do something if command execution succeeds
} else {
// do something on failure
}