2013-05-17 15 views

回答

11

是的。 print將其輸出發送到「選定」文件句柄,該文件句柄通常爲STDOUT。但Perl提供了select函數供您更改。

select(STDERR); 
&test;   # send output to STDERR 
select(STDOUT); # restore default output handle 

select函數返回先前選定的文件句柄,這樣你就可以抓住它並在以後恢復它。

my $orig_select = select(STDERR); 
&test; 
select($orig_select); 
+0

+1注意,在測試(致命異常)會留下一個非標準FILEHANDLE選擇()d,這是爲什麼我在本地回答下面的答案。 – pilcrow

9

Perl的通過local()動態作用域不經常使用,但是這在我看來是因爲它具有良好的應用:

test(); # to stdout 
{ 
    open(local *STDOUT, ">&STDERR") or die "dup out to err: $!"; 
    test(); # to stderr, locally calling it "STDOUT" 
} 
test(); # to stdout again 

在上面的塊test()調用 - 以及任何東西test()本身可能會調用 - 將STDOUT動態限定爲您的STDERR副本。當控制離開塊,即使通過die() ING,STDOUT將恢復到不管它是塊

廣義前:

sub out2err(&) { 
    my $user_block = shift; 
    open(local *STDOUT, ">&STDERR") or die $!; 
    $user_block->(); 
} 

test();    # to stdout 
out2err { test() }; # to stderr 
test();    # to stdout 
+1

+1即使給定函數顯式地打印到「STDOUT」,這也是可行的。 – chepner

3

同時,你也可以「捕獲子程序的打印輸出變量「。

只是傳遞一個標量裁判open

#! /usr/bin/env perl 
use common::sense; 
use autodie; 

sub tostring (&) { 
    my $s; 
    open local *STDOUT, '>', \$s; 
    shift->(); 
    $s 
} 

sub fake { 
    say 'lalala'; 
    say 'more stuff'; 
    say 1 + 1, ' = 2'; 
    say for @_; 
} 

for (tostring { fake(1, 2, 3) }) { 
    s/\n/\\n/g; 
    say "Captured as string: >>>$_<<<"; 
} 

輸出:

Captured as string: >>>lalala\nmore stuff\n2 = 2\n1\n2\n3\n<<< 
相關問題