【问题标题】:With perl CGI print on webpage STDOUT of executed command gradually随着 perl CGI 在网页上打印执行命令的 STDOUT 逐渐
【发布时间】:2015-04-11 04:00:37
【问题描述】:

我在 perl 中有一个 CGI 脚本,它运行带有虚拟目标的 swi-prolog:

它写“1”然后在一秒钟后在新行上写“2”等最后在新行上写“end”

我的目标是获得一个网页,其中 1、2、3、end逐渐写入,如果您执行此 prolog 代码,它会在终端中发生。

perl CGI的mwe:

#!/usr/bin/perl
use warnings;
use strict;
use diagnostics;
use CGI;

print "Content-type: text/html\n\n";

print <<EOF;
<html>
<head><title>Title</title></head>
<body>
EOF

my $out = `swipl -g 'writeln(1), sleep(1), writeln(2), sleep(1), writeln(3), sleep(1),  writeln(end)' -t halt`;
print "<pre>$out</pre>";

print <<EOF;
</body>
</html>
EOF
exit;

【问题讨论】:

  • 可以通过从服务器发送四个单独的页面来做到这一点,但时间会非常不准确。这样做的方法是在浏览器中运行的页面中嵌入一些 JavaScript。由于您只是出于好奇而这样做,我建议您找到其他东西

标签: perl cgi


【解决方案1】:

反引号不会按您希望的方式工作。 Perl 将生成子进程并等待它完成(sleep 语句和所有)。然后它的输出将被分配给$out & 只有这样你的脚本才会继续,一次打印单个字符串$out

您应该使用管道:

open my $program_pipe, '-|', 'unbuffer', 'swipl', '-g', q{writeln(1), yada yada}
    or die 'Help me Rhonda';
local $| = 1; # we don't want the web server waiting on us as we wait on the kid.
while (my $line = <$program_pipe>) {
  print $line;
}

您可能希望确保您的子程序在每个 sleep 之前刷新输出,否则您会在不可预知的点暂停,因为在程序休眠时任何缓冲的输出都将保持未写入状态。 unbuffer 为孩子创建了一个伪 tty,这“愚弄”了大多数程序执行行缓冲而不是块缓冲。

为了进行最后的润色,您可能希望首先使用一些 JavaScript 来完成文档,然后使用 AJAX 或 web 套接字之类的技术来传递额外的内容...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-12-23
    • 2014-11-10
    • 1970-01-01
    • 2015-03-19
    • 2013-12-30
    • 1970-01-01
    • 1970-01-01
    • 2017-04-14
    相关资源
    最近更新 更多