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

发布于 2024-09-15 05:43:21 字数 297 浏览 3 评论 0原文

我有一个 CGI 脚本,运行大约需要 1 分钟。目前,Apache 仅在该过程完成后才将结果返回给浏览器。

我怎样才能让它像在终端上运行一样显示输出?

这是一个演示该问题的示例

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

I have a CGI script which takes about 1 minute to run. Right now Apache only returns results to the browser once the process has finished.

How can I make it show the output like it was run on a terminal?

Here is a example which demonstrates the problem.

I want to see the numbers 1 to 5 appear as they are printed.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

心清如水 2024-09-22 05:43:21

我必须禁用 mod_deflate 才能使块模式与 apache 一起工作,

我没有找到另一种方法让我的 cgi 禁用自动编码到 gzip。

I had to disable mod_deflate to have chunk mode working with apache

I did not find another way for my cgi to disable auto encoding to gzip.

甜`诱少女 2024-09-22 05:43:21

这里有几个因素在起作用。为了消除一些问题,Apache 和 bash 不缓冲任何输出。您可以使用此脚本进行验证:

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

但是,将其提供给浏览器,您将得到不同的结果,具体取决于浏览器。在我的系统 Mac OS X 10.5.8 上,我发现浏览器之间存在不同的行为。在 Safari、Chrome 和 Firefox 4 beta 中,直到我发送了大约 1000 个字符(我猜是 1024 个字符,包括标头或类似的字符),我才开始看到输出,但我还没有将其缩小到确切的行为)。在 Firefox 3.6 中,它会立即开始显示。

我猜测这种延迟是由于 内容类型嗅探 或 字符编码嗅探,正在标准化过程中。我尝试看看是否可以通过指定正确的内容类型和字符编码来解决延迟问题,但没有成功。您可能必须发送一些填充数据(如果您使用 HTML 而不是纯文本,这将很容易在无形中完成),以超出初始缓冲区。

一旦开始流式传输 HTML 而不是纯文本,HTML 的结构也很重要。有些内容可以逐步显示,有些则不能。例如,将

流式传输到正文中,不带样式,效果很好,并且可以在到达时逐步显示。如果您尝试打开

 标签,然后将内容流式传输到该标签中,基于 Webkit 的浏览器将等到看到关闭标签后才尝试将其布局,而 Firefox 很乐意显示逐步进行。我不知道所有的极端情况;你必须尝试一下,看看什么对你有用。

无论如何,我希望这可以帮助您入门。如果您还有其他问题,请告诉我!

1\n' # This is a Bash-ism, since it's pretty hard to get a newline chunk

但是,将其提供给浏览器,您将得到不同的结果,具体取决于浏览器。在我的系统 Mac OS X 10.5.8 上,我发现浏览器之间存在不同的行为。在 Safari、Chrome 和 Firefox 4 beta 中,直到我发送了大约 1000 个字符(我猜是 1024 个字符,包括标头或类似的字符),我才开始看到输出,但我还没有将其缩小到确切的行为)。在 Firefox 3.6 中,它会立即开始显示。

我猜测这种延迟是由于 内容类型嗅探 或 字符编码嗅探,正在标准化过程中。我尝试看看是否可以通过指定正确的内容类型和字符编码来解决延迟问题,但没有成功。您可能必须发送一些填充数据(如果您使用 HTML 而不是纯文本,这将很容易在无形中完成),以超出初始缓冲区。

一旦开始流式传输 HTML 而不是纯文本,HTML 的结构也很重要。有些内容可以逐步显示,有些则不能。例如,将

流式传输到正文中,不带样式,效果很好,并且可以在到达时逐步显示。如果您尝试打开


无论如何,我希望这可以帮助您入门。如果您还有其他问题,请告诉我!

2\n' # character portably.

但是,将其提供给浏览器,您将得到不同的结果,具体取决于浏览器。在我的系统 Mac OS X 10.5.8 上,我发现浏览器之间存在不同的行为。在 Safari、Chrome 和 Firefox 4 beta 中,直到我发送了大约 1000 个字符(我猜是 1024 个字符,包括标头或类似的字符),我才开始看到输出,但我还没有将其缩小到确切的行为)。在 Firefox 3.6 中,它会立即开始显示。

我猜测这种延迟是由于 内容类型嗅探 或 字符编码嗅探,正在标准化过程中。我尝试看看是否可以通过指定正确的内容类型和字符编码来解决延迟问题,但没有成功。您可能必须发送一些填充数据(如果您使用 HTML 而不是纯文本,这将很容易在无形中完成),以超出初始缓冲区。

一旦开始流式传输 HTML 而不是纯文本,HTML 的结构也很重要。有些内容可以逐步显示,有些则不能。例如,将

流式传输到正文中,不带样式,效果很好,并且可以在到达时逐步显示。如果您尝试打开

无论如何,我希望这可以帮助您入门。如果您还有其他问题,请告诉我!

There are several factors at play here. To eliminate a few issues, Apache and bash are not buffering any of the output. You can verify with this script:

#!/bin/sh

cat <<END
Content-Type: text/plain

END

for i in $(seq 1 10)
do
    echo $i
    sleep 1
done

Stick this somewhere that Apache is configured to execute CGI scripts, and test with 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

When I do this, I see in netcat each number appearing once per second, as intended.

Note that my version of Apache, at least, applies the chunked transfer encoding automatically, presumably because I didn't include a Content-Length; if you return the Transfer-Encoding: chunked header yourself, then you need to encode the output of your script in the chunked transfer encoding. That's pretty easy, even in a shell script:

chunk () {
    printf '%x\r\n' "${#1}"  # Length of the chunk in hex, CRLF
    printf '%s\r\n' "$1"     # Chunk itself, CRLF
}

chunk 

However, serve this to a browser, and you'll get varying results depending on the browser. On my system, Mac OS X 10.5.8, I see different behaviors between my browsers. In Safari, Chrome, and Firefox 4 beta, I don't start seeing output until I've sent somewhere around 1000 characters (I would guess 1024 including the headers, or something like that, but I haven't narrowed it down to the exact behavior). In Firefox 3.6, it starts displaying immediately.

I would guess that this delay is due to content type sniffing, or character encoding sniffing, which are in the process of being standardized. I have tried to see if I could get around the delay by specifying proper content types and character encodings, but without luck. You may have to send some padding data (which would be pretty easy to do invisibly if you use HTML instead of plain text), to get beyond that initial buffer.

Once you start streaming HTML instead of plain text, the structure of your HTML matters too. Some content can be displayed progressively, while some cannot. For instance, streaming down <div>s into the body, with no styling, works fine, and can display progressively as it arrives. If you try to open a <pre> tag, and just stream content into that, Webkit based browsers will wait until they see the close tag to try to lay that out, while Firefox is happy to display it progressively. I don't know all of the corner cases; you'll have to experiment to see what works for you.

Anyhow, I hope this helps you get started. Let me know if you have any more questions!

1\n' # This is a Bash-ism, since it's pretty hard to get a newline chunk

However, serve this to a browser, and you'll get varying results depending on the browser. On my system, Mac OS X 10.5.8, I see different behaviors between my browsers. In Safari, Chrome, and Firefox 4 beta, I don't start seeing output until I've sent somewhere around 1000 characters (I would guess 1024 including the headers, or something like that, but I haven't narrowed it down to the exact behavior). In Firefox 3.6, it starts displaying immediately.

I would guess that this delay is due to content type sniffing, or character encoding sniffing, which are in the process of being standardized. I have tried to see if I could get around the delay by specifying proper content types and character encodings, but without luck. You may have to send some padding data (which would be pretty easy to do invisibly if you use HTML instead of plain text), to get beyond that initial buffer.

Once you start streaming HTML instead of plain text, the structure of your HTML matters too. Some content can be displayed progressively, while some cannot. For instance, streaming down <div>s into the body, with no styling, works fine, and can display progressively as it arrives. If you try to open a <pre> tag, and just stream content into that, Webkit based browsers will wait until they see the close tag to try to lay that out, while Firefox is happy to display it progressively. I don't know all of the corner cases; you'll have to experiment to see what works for you.

Anyhow, I hope this helps you get started. Let me know if you have any more questions!

2\n' # character portably.

However, serve this to a browser, and you'll get varying results depending on the browser. On my system, Mac OS X 10.5.8, I see different behaviors between my browsers. In Safari, Chrome, and Firefox 4 beta, I don't start seeing output until I've sent somewhere around 1000 characters (I would guess 1024 including the headers, or something like that, but I haven't narrowed it down to the exact behavior). In Firefox 3.6, it starts displaying immediately.

I would guess that this delay is due to content type sniffing, or character encoding sniffing, which are in the process of being standardized. I have tried to see if I could get around the delay by specifying proper content types and character encodings, but without luck. You may have to send some padding data (which would be pretty easy to do invisibly if you use HTML instead of plain text), to get beyond that initial buffer.

Once you start streaming HTML instead of plain text, the structure of your HTML matters too. Some content can be displayed progressively, while some cannot. For instance, streaming down <div>s into the body, with no styling, works fine, and can display progressively as it arrives. If you try to open a <pre> tag, and just stream content into that, Webkit based browsers will wait until they see the close tag to try to lay that out, while Firefox is happy to display it progressively. I don't know all of the corner cases; you'll have to experiment to see what works for you.

Anyhow, I hope this helps you get started. Let me know if you have any more questions!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文