我使用

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)的时间,它只是打印出什么。

我找不到任何理由为什么它这样的行为。我想知道的任何人都遇到类似的问题,因为我吗?

有帮助吗?

解决方案

我要明确地保存和恢复。它适用于我的情况。但我不知道为什么。

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

其他提示

尝试:

local $|=1;

print之前。这绕过缓冲。

请参阅 http://perldoc.perl.org/perlvar html的#把手型%3Eautoflush%28EXPR%29

缓冲是最可能出现的问题,前面已经提到的,但有如果不为你工作,无论出于何种原因的另一种方法。您可以使用经常被忽略的一个带参数的选择()内置更改默认的输出文件句柄的打印输出。

我敢打赌,这是的mod_perl的相互作用,以及STDOUT水珠的重新分配 - 您可以有效运行的Perl的一个实例中的Web服务器,那么这将导致竞争条件时local超出范围,并当各种print的和close的发生。

这基本上是我的猜测,我不知道肯定是发生了这样记住这一点。粗略地说比赛条件是,当你这样做之间:

local *STDOUT = $nullfh;

和当该local超出范围。我认为,到Web服务器请求作为不同的线程处理(因为我们使用的mod_perl),每个线程可能能够看到新的价值,为水珠。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top