暂时将STDOUT重定向到/ dev / null - 不能一直工作

时间:2009-06-28 09:10:02

标签: perl printing buffer

我正在使用

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

参考STDIN, STDOUT, and STDERR Streams

#!/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 个答案:

答案 0 :(得分:5)

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

# 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: $!";

答案 1 :(得分:2)

尝试:

local $|=1;
print之前

。这绕过了缓冲。

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

答案 2 :(得分:1)

我敢打赌这是mod_perl的交互,以及STDOUT glob的重新分配 - 你实际上是在web服务器上运行了一个perl实例,那么这将导致{{1超出范围,当各种localprint发生时。

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

close

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

答案 3 :(得分:1)

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