2009-06-28 73 views
4

我使用暫時stdout重定向到/ dev/null的 - 不是所有的工作時間

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)時間,它只是打印出什麼。

我找不到任何理由爲什麼這樣做。我可以知道你們中的任何人遇到類似的問題嗎?

回答

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

我敢打賭,這是一個mod_perl和STDOUT glob的重新分配 - 你在網絡服務器上有效地運行一個perl實例,那麼這將導致當local超出範圍時的競爭條件,並且當各種各樣的printclose發生。

這基本上是我的猜測,我不確定它發生了什麼,所以記住這一點。粗略地說比賽條件是,當你這樣做之間:

local *STDOUT = $nullfh; 

當這個local超出範圍。我認爲對web服務器的請求被處理爲不同的線程(因爲我們使用的是mod_perl),並且每個線程都可以看到glob的新值。

+0

你能稍微詳細些嗎?這沒有什麼意義。 – ysth 2009-06-30 02:10:02

1

緩衝是最可能出現的問題,前面已經提到的,但有如果不爲你工作,無論出於何種原因的另一種方法。您可以使用內置的忽略one-arg select()來更改打印輸出的默認輸出文件句柄。