douji1077
2012-06-30 19:12
浏览 242

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

BACKGROUND:

Right now, in our company we have a PHP based app to automate our report building. It works like this:

  1. A webpage with a form generates a ini file with some configurations that is saved localy
  2. a PHP CLI script accepts the ini file generated on step 1 and based on it, creates a directory with documents whose data is fetched from the internet. (takes between 5 and 10 minutes to complete)
  3. Another web form explores the content of the folder, does some validation and shows the contents of the directory as a preview.

Between any of those steps, user input is needed and sometimes the user needs to interrupt the script 2 to correct some of the ini values.


PROBLEM:

We want to run the cli script in the web browser, so that after the user clicks a "build" button, the ini file (or an array) is generated and automatically passed to the second script. But the idea is to have that script run independently (simulating another "thread"), verbosing everything it is doing along the way in order to let the user interrupt if he needs to. Something like running the script in the command line, in which each step is verbosed.


We though using AJAX, but it waits for the server to complete its answer before printing anything in the web browser. An iFrame doesn't work also since we can't manipulate its src attributes and contents with javascript.

So, how can we "simulate" a command shell output? any tip n the right direction would be very appreciated.

NOTE: The script will be always used in "localhost", no need for remote access!


SOLUTION

I ended up doing something even easier, based on the sugestions:

  • Dumped the contents of the form ($_POST) to a session var $_SESSION['FORM'].
  • Created a $_SESSION[form-complete] flag that would be set to true when user clicked the "build" button.
  • If the $_SESSION[form-complete] was true, the server would show an iframe pointing to the "CLI SCRIPT" whose arguments were the previously dumped session variables.
  • The CLI Script also has ob_implicit_flush(true); ob_end_flush(); so that the output won't be cached.
  • At the end of the script the $_SESSION variable is clean and the session destroyed

图片转代码服务由CSDN问答提供 功能建议

背景:

现在,在我们公司,我们有一个基于PHP的 应用程序自动化我们的报告建设。 它的工作方式如下:

  1. 带有表单的网页会生成一个ini文件,其中包含一些保存的配置。
  2. 一个PHP CLI脚本 接受在步骤1中生成的ini文件并基于该文件创建一个目录,其中包含从互联网获取数据的文档。 (需要5到10分钟才能完成)
  3. 另一个Web表单浏览文件夹的内容,进行一些验证并将目录的内容显示为预览。 < / ol>

    在任何这些步骤之间,需要用户输入,有时用户需要中断脚本2来纠正一些ini值。


    \ n

    问题:

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


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

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

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

    解决方案

    基于消息,我最终做了一些更容易的事情:

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

  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

2条回答 默认 最新

  • douzhi2017 2012-06-30 19:17
    已采纳

    An iFrame doesn't work also since we can't manipulate its src attributes and contents with javascript.

    You can, provided that the iframe resides on the same host as the parents pages (e.g. localhost). AJAX naturally doesn't support cross-domain requests either, so if you have AJAX working, iframes will follow too.

    Your easiest bet will be to pipe the output to a temporary file and then have your 'separate thread' be an iframe/AJAX calls that retrieves the output. If it's running on localhost, then bandwidth optimisations for this would be a bit pointless (unless the log gets really long).


    A little example:

    Suppose we want to run ./long_script. This is how we can do it.

    1. system('./long_script > /tmp/file 2>&1 &'); (pipe all output to /tmp/file, then run it in the background)
    2. Make a PHP script that does something like this (you'll need a secure way of getting the filename, preferably a session variable, or a sanitized $_GET variable):

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

    3. Put that PHP script in an iframe. The Javascript will cause an auto-reload every 1s.


    Alternative:

    You can use popen to have a process handle, fread then flush the data (set ob_implicit_flush(true)) to the browser (so it doesn't wait to get all the output from the process, and push it all at once).

    已采纳该答案
    打赏 评论
  • doumi7854 2012-06-30 19:31

    Well, the step 2 can be a page like this:

    <!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>
    

    The call ajax (to a PHP) write in a "control" file your command (stop,pause) OR some new info (eg: a new info file).

    Periodically your step2cli.php check the "control" file. If exist, parse it and remove it, and then, of course apply new info.

    打赏 评论

相关推荐 更多相似问题