任何人都可以帮助,如何使用 php 从 linux 中的命令终端输出读取实时输出。
下面是我试过但没有用的代码:
<?php
if (isset($_POST['pyinp'])){
$cmd = "ping 127.0.0.1";
$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
);
flush();
$process = proc_open($cmd, $descriptorspec, $pipes, realpath('./'), array());
echo "<pre>";
if (is_resource($process)) {
while ($s = fgets($pipes[1])) {
print $s;
flush();
}
}
echo "</pre>";
}
?>
<!DOCTYPE html>
<html>
<body>
<form action="#" method="POST">
<input name = "pyinp" type="submit">
</form>
</body>
</html>
我收到提交按钮,当我按下提交时,什么也没有。
我是 html 和 php 的新手。我只是在线编码。
下面的代码是有效的:
<!DOCTYPE html>
<html>
<body>
<form action="#" method="POST">
<input name = "pyinp" type="submit">
</form>
<?php
if (isset($_POST['pyinp'])){
$cmd = "ping 127.0.0.1";
$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
);
echo "<pre>";
if( ($fp = popen("ls -l", "r")) ) {
while( !feof($fp) ){
echo fread($fp, 1024);
flush(); // you have to flush buffer
}
fclose($fp);
}
}
?>
</body>
</html>
但如果我用 ping 127.0.0.1 替换它就不起作用
谢谢
最佳答案
TL;DR:在 HTML 文档关闭之前有一个无限循环。
让我重写您的代码,以便 ping 输出应该进入 <body>...</body>
容器:
<!DOCTYPE html>
<html>
<body>
<form action="#" method="POST">
<input name = "pyinp" type="submit">
</form>
<?php
if (isset($_POST['pyinp'])){
$cmd = "ping 127.0.0.1";
$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
);
flush();
$process = proc_open($cmd, $descriptorspec, $pipes, realpath('./'), array());
echo "<pre>";
if (is_resource($process)) {
while ($s = fgets($pipes[1])) {
print $s;
flush();
}
}
echo "</pre>";
}
?>
</body>
</html>
现在,让我们做一个思想实验。你第一次GET
在页面上,您会看到一个带有按钮的表单。一切都很好。你点击按钮。表格得到 POST
埃德回到自己。然后会发生什么?
首先输出静态HTML:
<!DOCTYPE html>
<html>
<body>
<form action="#" method="POST">
<input name = "pyinp" type="submit">
</form>
然后 PHP 引擎激活:
<?php
然后 PHP 看到按钮被按下,并做了一堆东西来设置管道(所有这些都是正确的,顺便说一句,你可以在命令行上检查):
$cmd = "ping 127.0.0.1";
$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
);
flush();
$process = proc_open($cmd, $descriptorspec, $pipes, realpath('./'), array());
echo "<pre>";
然后它检查连接是否建立(你真的应该在这里添加一个 else
):
if (is_resource($process)) {
现在呢?
while ($s = fgets($pipes[1])) {
print $s;
flush();
}
没错:一个永不结束的 while 循环!这永远旋转和旋转。与此同时,这些都没有被执行:
?>
</body>
</html>
因此浏览器永远不会看到主体关闭。那又怎样,你问?嗯,在关闭所有标签之前,浏览器没有义务显示内容。
“但是,但是,它有时确实有效!”你喊。当然,有时它会起作用。但这次看起来加载刚刚停滞,而不仅仅是糟糕的 HTML。浏览器不知道你有一个永远不会结束的无限循环,所以它只是在等待你关闭你的输出。
Web authors beware - unless you want to appear as an example in a Webkit error tolerance code - write well formed HTML.
如果你想看到这个效果,那就不要无限循环:
$i = 0;
while ($s = fgets($pipes[1])) {
print $s;
flush();
if (4 < $i++) { break; }
}
或者加载 Javascript,回调执行该工作的脚本。
关于php - 读取命令行输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45863646/