2010-12-11 107 views
8

我想将STDERRSTDOUT重定向到变量。我做到了。如何将STDOUT和STDERR重定向到变量

close(STDOUT); 
close(STDERR); 

my $out; 
open(STDOUT, ">>", \$out); 
open(STDERR, ">>", \$out); 

for(1..10) 
{ 
    print "print\n"; # this is ok. 
    warn "warn\n"; # same 
    system("make"); # this is lost. neither in screen nor in variable. 
} 

问题system。我希望这个调用的输出也被捕获。

回答

3

您是否想要捕获变量中的输出?如果是这样,您可以使用反引号或qx{}进行适当的重定向。例如,你可以使用:

#/usr/bin/env perl 
use strict; 
use warnings; 

# Ensure we have a way to write messages 
open my $fh, '>', "output" or die; 

close(STDOUT); 
close(STDERR); 

my $out; 
open(STDOUT, ">>", \$out) or do { print $fh, "failed to open STDOUT ($!)\n"; die }; 
open(STDERR, ">>", \$out) or do { print $fh, "failed to open STDERR ($!)\n"; die }; 

foreach my $i (1..10) 
{ 
    print "print $i\n"; 
    warn "warn $i\n"; 
    my $extra = qx{make pth$i 2>&1}; 
    print $fh "<<$i>><<$out>><<$extra>>\n"; 
} 

(我碰巧在目录中有程序PTH1,PTH2和pth3 - 它们是由OK; pth4及以上错误写入标准错误;重定向是必要的。)

您应该经常检查操作是否成功,如open()

这是为什么这是必要的?因为写入变量需要进行写作的过程的合作 - 而make不知道如何合作。

2

发生这种情况的原因是STDOUT和STDERR“文件句柄”是而不是等同于shell提供给perl二进制文件的stderr和stdout句柄。为了达到你想要的效果,你应该使用open而不是system

+0

$ out。= qx {make};但是不认为这是一个好方法。 – Deck 2010-12-11 06:32:45

+2

@Israfil:这是*做的方法。 – 2010-12-11 06:39:11

1

为什么不是use IPC::Open3

+0

因为它在Win32上无法正常工作。 – dolmen 2011-04-16 10:24:01

0

redirect and restore STDOUT有几种方法。他们中的一些人也与STDERR一起工作。这里是我的两个最爱:

使用select

my $out; 
open my $fh, ">>", \$out; 
select $fh; 
print "written to the variable\n"; 
select STDOUT; 
print "written to original STDOUT\n"; 

使用local

my $out 
do { 
    local *STDOUT; 
    open STDOUT, ">>", \$out; 
    print "written to the variable\n"; 
}; 
print "written to original STDOUT\n"; 

享受。

相关问题