Я пытаюсь выполнить скрипт bash из php и получить его вывод в реальном времени.
Я применяю ответы, найденные здесь:
Однако они не работают для меня.
Когда я вызываю скрипт.sh таким образом, он отлично работает:
<?php
$output = shell_exec("./test.sh");
echo "<pre>$output</pre>";
?>
Однако при выполнении:
<?php
echo '<pre>';
passthru(./test.sh);
echo '</pre>';
?>
или:
<?php
while (@ ob_end_flush()); // end all output buffers if any
$proc = popen(./test.sh, 'r');
echo '<pre>';
while (!feof($proc))
{
echo fread($proc, 4096);
@ flush();
}
echo '</pre>';
?>
У меня нет вывода в моем браузере.
Я также попытался вызвать переменную вместо сценария в обоих случаях, я имею в виду:
<?php
$output = shell_exec("./test.sh");
echo '<pre>';
passthru($output);
echo '</pre>';
?>
Это мой скрипт test.sh:
#!/bin/bash
whoami
sleep 3
dmesg
Используйте следующее:
<?php
ob_implicit_flush(true);
ob_end_flush();
$cmd = "bash /path/to/test.sh";
$descriptorspec = array(
0 => array("pipe", "r"), // stdin is a pipe that the child will read from
1 => array("pipe", "w"), // stdout is a pipe that the child will write to
2 => array("pipe", "w") // stderr is a pipe that the child will write to
);
$process = proc_open($cmd, $descriptorspec, $pipes, realpath('./'), array());
if (is_resource($process)) {
while ($s = fgets($pipes[1])) {
print $s;
}
}
?>
Измените test.sh на:
#!/bin/bash
whoami
sleep 3
ls /
Объяснение:
dmesg требует разрешений. Для этого вам необходимо предоставить права пользователя веб-сервера. В моем случае apache2 запускается через пользователя www-data.
ob_implicit_flush(true)
: Включает скрытую ob_implicit_flush(true)
. Неявная промывка приведет к операции флеша после каждого выходного вызова, так что явные вызовы flush()
больше не понадобятся.
ob_end_flush()
: Отключает буферизацию вывода, поэтому мы сразу видим результаты.
stream_select()
+ stream_get_contents()
лучше подходят для работы, так как fgets()
прекращает чтение, когда появляется stream_get_contents()
что, скорее всего, произойдет). Проверьте мой предыдущий ответ здесь: stackoverflow.com/a/37526704/1957951
passthru("./test.sh");
- это не работает даже так?