代码之家  ›  专栏  ›  技术社区  ›  hendry

用Apache显示一个长时间运行的shell进程

  •  5
  • hendry  · 技术社区  · 14 年前

    我有一个 CGI 运行大约需要1分钟的脚本。现在,Apache只在流程完成后将结果返回到浏览器。

    这是一个 example 这说明了问题所在。

    我想看到数字1到5在打印时出现。

    2 回复  |  直到 12 年前
        1
  •  6
  •   tardyp    12 年前

    我不得不禁用mod_deflate,让块模式与apache一起工作

    我没有找到其他方法让我的cgi禁用gzip的自动编码。

        2
  •  3
  •   Ingo Karkat    11 年前

    #!/bin/sh
    
    cat <<END
    Content-Type: text/plain
    
    END
    
    for i in $(seq 1 10)
    do
        echo $i
        sleep 1
    done
    

    将此粘贴到Apache配置为执行CGI脚本的地方,并使用netcat进行测试:

    $ nc localhost 80
    GET /cgi-bin/chunkit.cgi HTTP/1.1
    Host: localhost
    
    HTTP/1.1 200 OK
    Date: Tue, 24 Aug 2010 23:26:24 GMT
    Server: Apache/2.2.14 (Unix) mod_ssl/2.2.14 OpenSSL/0.9.7l DAV/2
    Transfer-Encoding: chunked
    Content-Type: text/plain
    
    2
    1
    
    2
    2
    
    2
    3
    
    2
    4
    
    2
    5
    
    2
    6
    
    2
    7
    
    2
    8
    
    2
    9
    
    3
    10
    
    0
    

    当我这样做时,我在netcat中看到每个数字都会按预期每秒出现一次。

    请注意,至少我的Apache版本会自动应用分块传输编码,可能是因为我没有包含 Content-Length ;如果您归还 Transfer-Encoding: chunked 头文件,然后您需要将脚本的输出编码为分块传输编码。这很简单,即使是在shell脚本中:

    chunk () {
        printf '%x\r\n' "${#1}"  # Length of the chunk in hex, CRLF
        printf '%s\r\n' "$1"     # Chunk itself, CRLF
    }
    
    chunk $'1\n' # This is a Bash-ism, since it's pretty hard to get a newline
    chunk $'2\n' # character portably.
    

    但是,将此服务提供给浏览器,您将根据浏览器得到不同的结果。在我的系统macosx10.5.8上,我看到浏览器之间的不同行为。在Safari、Chrome和firefox4beta中,只有在发送了大约1000个字符之后,我才会开始看到输出(我猜1024个字符包含了标题,或者类似的东西,但是我还没有把它缩小到确切的行为)。在Firefox3.6中,它会立即开始显示。

    content type sniffing ,或 character encoding sniffing ,正在标准化过程中。我曾试图通过指定适当的内容类型和字符编码来避免延迟,但运气不佳。您可能需要发送一些填充数据(如果您使用HTML而不是纯文本,这将很容易以不可见的方式完成),以超出初始缓冲区。

    <div> <pre> 基于Webkit的浏览器会等到看到close标记时才尝试将其显示出来,而Firefox则乐于逐步显示它。我不知道所有的角落案例,你得试验看看什么对你有用。