读取命令行输出

时间:2017-08-24 14:00:37

标签: 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替换

,它就不起作用

由于

1 个答案:

答案 0 :(得分:0)

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();
}

这是对的:一个永远不会结束的循环!这种旋转和旋转永远。与此同时,这一切都没有被执行:

?>

</body>
</html>

因此浏览器永远不会看到正文关闭。那么,你问什么?好吧,浏览器没有义务在关闭所有标签之前显示内容。

“但是,它确实有效!”你喊。当然,有时它有效。但这一次看起来加载只是停滞,而不仅仅是糟糕的HTML。浏览器不知道你有一个永无止境的无限循环,所以它只是等着你关闭你的输出。

In general

  

Web作者要小心 - 除非您想在Webkit容错代码中作为示例出现 - 编写格式良好的HTML。

如果你想看到这个工作,那么不要做无限循环:

$i = 0;
while ($s = fgets($pipes[1])) {
    print $s;
    flush();
    if (4 < $i++) { break; }
}

或者加载Javascript,回调一个完成工作的脚本。

相关问题