4

我在用

Server version: Apache/1.3.34 (Debian)
mod_perl - 1.29

通过参考STDIN、STDOUT 和 STDERR 流

#!/usr/bin/perl5
package main;

use strict 'vars';

{
    # Our mighty holy legacy code love to print out message in the middle of operation. Shihh....
    # Let's quietly redirect those message to /dev/null.
    my $nullfh = Apache::gensym( );
    open $nullfh, '>/dev/null' or warn "Can't open /dev/null: $!";
    local *STDOUT = $nullfh;
    print "BYE BYE WORLD";    # Shouldn't show in webpage.
    close $nullfh;
}

print "X BEGIN HELLO WORLD";  # Should show in webpage.

我意识到它并不是一直都在工作。例如,我刷新页面 10 次。x 次它会打印出“X BEGIN HELLO WORLD”。(10-x)时间它什么也没打印出来。

我找不到任何理由为什么它会这样。我可以知道你们中的任何人都遇到过和我类似的问题吗?

4

4 回答 4

6

我需要明确存储和恢复。它适用于我的情况。但我不确定为什么。

# Take copies of the file descriptors
open OLDOUT, '>&STDOUT';
my $returned_values = 0;
{
    # Our mighty holy legacy code love to print out message in the middle of operation. Shihh....
    # Let's quietly redirect those message to /dev/null.
    local *STDOUT;
    open STDOUT, '>/dev/null' or warn "Can't open /dev/null: $!";
    print "BYE BYE WORLD";    # Shouldn't show in webpage.
    close STDOUT;
}
# Restore stdout.
open STDOUT, '>&OLDOUT' or die "Can't restore stdout: $!";
# Avoid leaks by closing the independent copies.
close OLDOUT or die "Can't close OLDOUT: $!";
于 2009-06-30T01:10:39.883 回答
2

尝试:

local $|=1;

之前print。这绕过了缓冲。

请参阅http://perldoc.perl.org/perlvar.html#HANDLE-%3Eautoflush%28EXPR%29

于 2009-06-28T10:38:03.530 回答
1

如前所述,缓冲是最有可能出现的问题,但如果由于某种原因对您不起作用,还有另一种方法。您可以使用内置的经常忽略的单参数 select() 来更改打印输出的默认输出文件句柄。

于 2009-06-28T21:56:09.820 回答
1

我敢打赌,这是 mod_perl 的交互,以及 glob 的重新分配- 您实际上是在网络服务器中运行 perl的STDOUT一个实例,那么这将导致当local超出范围以及各种print并且close发生了。

这基本上是我的猜测,我不确定它是否正在发生,所以请记住这一点。粗略地说,当你这样做时,竞争条件将介于:

local *STDOUT = $nullfh;

当这local超出范围时。我认为对 Web 服务器的请求是作为不同的线程处理的(因为我们使用的是 mod_perl),并且每个线程都可以看到 glob 的新值。

于 2009-06-28T10:01:25.180 回答