php - 读取命令行输出

标签 php html linux

任何人都可以帮助,如何使用 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。浏览器不知道你有一个永远不会结束的无限循环,所以它只是在等待你关闭你的输出。

In general :

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/

相关文章:

php - 生成私有(private)、唯一、安全的 URL

jquery - 在选择框外部单击时缩回选择选项

c - TCP/IP 套接字,读取错误? (Linux)

linux - 如果PDF阅读器在最后一页,如何查询?

javascript - Datatable-bootstrap仅在第一页上起作用。

php - 'C :\wmic' is not recognized as an internal or external command, 可运行的程序或批处理文件

php - 为什么 `FILTER_VALIDATE_NUMBER_FLOAT` 常量会去掉小数位字符?

html - IE中的Image onLoad问题

html - z-index 和汉堡菜单

linux - 让 gdb 自动读取 ./.gdbinit