目前,在我们公司,我们有一个基于PHP的应用程序来自动化我们的报告构建。它的工作原理如下:
在任何这些步骤之间,需要用户输入,有时用户需要中断脚本2来纠正一些ini值。
我们希望在Web浏览器中运行cli脚本,以便在用户单击“构建”按钮后,生成ini文件(或数组)并自动传递给第二个脚本。但我们的想法是让该脚本独立运行(模拟另一个“线程”),详细说明它正在做的一切,以便让用户在需要时进行中断。类似于在命令行中运行脚本,其中每个步骤都是详细的。
我们虽然使用AJAX,但它等待服务器在Web浏览器中打印任何内容之前完成答案。 由于我们无法使用javascript操纵其src属性和内容,因此iFrame也不起作用。
那么,我们如何“模拟”命令shell输出呢?任何提示正确的方向都会非常感激。
注意:脚本将始终用于“localhost”,无需远程访问!
我最终做了一些更简单的事情,基于消遣:
ob_implicit_flush(true); ob_end_flush();
,因此不会缓存输出。答案 0 :(得分:3)
由于我们无法使用javascript操纵其src属性和内容,因此iFrame也不起作用。
您可以,只要iframe与父页面位于同一主机上(例如localhost
)。 AJAX自然也不支持跨域请求,所以如果你有AJAX工作,iframe也会跟着。
您最简单的选择是将输出传递给temporary file,然后让您的“单独线程”成为检索输出的iframe / AJAX调用。如果它在localhost上运行,那么对此进行带宽优化将毫无意义(除非日志真的长)。
假设我们想要运行./long_script
。这就是我们如何做到的。
system('./long_script > /tmp/file 2>&1 &');
(管道所有输出到/ tmp / file,然后在后台运行)创建一个类似于此的PHP脚本(您需要安全获取文件名的方式,最好是会话变量或已清理的$_GET
变量) :
<pre><?php echo file_get_contents('/tmp/file'); ?></pre><script>setTimeout("window.location.reload()", 1000);</script>
将该PHP脚本放在iframe中。 Javascript将每1秒自动重新加载一次。
您可以使用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