在Web浏览器中模拟命令shell输出

时间:2012-06-30 19:12:59

标签: php ajax

背景:

目前,在我们公司,我们有一个基于PHP的应用程序来自动化我们的报告构建。它的工作原理如下:

  1. 带有表单的网页会生成一个ini文件,其中包含一些保存为localy的配置
  2. PHP CLI脚本接受在步骤1中生成的ini文件,并基于该脚本创建一个目录,其中包含从Internet获取数据的文档。 (需要5到10分钟才能完成)
  3. 另一个网络表单浏览文件夹的内容,进行一些验证并将目录的内容显示为预览。
  4. 在任何这些步骤之间,需要用户输入,有时用户需要中断脚本2来纠正一些ini值。


    问题:

    我们希望在Web浏览器中运行cli脚本,以便在用户单击“构建”按钮后,生成ini文件(或数组)并自动传递给第二个脚本。但我们的想法是让该脚本独立运行(模拟另一个“线程”),详细说明它正在做的一切,以便让用户在需要时进行中断。类似于在命令行中运行脚本,其中每个步骤都是详细的。


    我们虽然使用AJAX,但它等待服务器在Web浏览器中打印任何内容之前完成答案。 由于我们无法使用javascript操纵其src属性和内容,因此iFrame也不起作用。

    那么,我们如何“模拟”命令shell输出呢?任何提示正确的方向都会非常感激。

    注意:脚本将始终用于“localhost”,无需远程访问!


    我最终做了一些更简单的事情,基于消遣:

    • 将表单内容($ _POST)转储到会话var $ _SESSION ['FORM']。
    • 创建了一个$ _SESSION [form-complete]标志,当用户点击“构建”按钮时,该标志将设置为true。
    • 如果$ _SESSION [form-complete]为true,服务器将显示一个指向“CLI SCRIPT”的iframe,其参数是先前转储的会话变量。
    • CLI脚本也有ob_implicit_flush(true); ob_end_flush();,因此不会缓存输出。
    • 在脚本结束时,$ _SESSION变量是干净的,会话被销毁

3 个答案:

答案 0 :(得分:3)

  

由于我们无法使用javascript操纵其src属性和内容,因此iFrame也不起作用。

您可以,只要iframe与父页面位于同一主机上(例如localhost)。 AJAX自然也不支持跨域请求,所以如果你有AJAX工作,iframe也会跟着。

您最简单的选择是将输出传递给temporary file,然后让您的“单独线程”成为检索输出的iframe / AJAX调用。如果它在localhost上运行,那么对此进行带宽优化将毫无意义(除非日志真的长)。


一个小例子:

假设我们想要运行./long_script。这就是我们如何做到的。

  1. system('./long_script > /tmp/file 2>&1 &');(管道所有输出到/ tmp / file,然后在后台运行)
  2. 创建一个类似于此的PHP脚本(您需要安全获取文件名的方式,最好是会话变量或已清理的$_GET变量) :

    <pre><?php echo file_get_contents('/tmp/file'); ?></pre><script>setTimeout("window.location.reload()", 1000);</script>

  3. 将该PHP脚本放在iframe中。 Javascript将每1秒自动重新加载一次。


  4. 替代:

    您可以使用popen来创建流程句柄,fread然后将数据(设置ob_implicit_flush(true))刷新到浏览器(因此它不会等待从中获取所有输出过程,并立即全部推送。)

答案 1 :(得分:1)

那么, 第2步可以是这样的页面:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <title></title>
</head>
<body>

<button onclick="javasctipt:ajaxCall('stop')">Stop</button>
<button onclick="javasctipt:ajaxCall('pause')">Pause</button>
...
<iframe src="step2cli.php">Output of cli here</iframe>

</body>
</html>

调用ajax(对PHP)在“控制”文件中写入命令(停止,暂停)一些新信息(例如:新信息文件)。

您的step2cli.php会定期检查“控制”文件。如果存在,解析并删除它,然后,当然应用新信息。

答案 2 :(得分:0)

此代码在 bash 中运行

url="google.com"
content=$(curl -L $url)
echo $content