如何将STDOUT和STDERR重定向到变量

Dec*_*eck 11 perl redirect stdout system stderr

我想重定向STDERRSTDOUT一个变量.我这样做了

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.
}
Run Code Online (Sandbox Code Playgroud)

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

Jon*_*ler 5

您是否正在寻求在变量中捕获输出?如果是这样,您可以使用反引号或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";
}
Run Code Online (Sandbox Code Playgroud)

(我碰巧在目录中有 pth1、pth2 和 pth3 程序 - 它们被设置为正常;pth4 及以上将错误写入 stderr;重定向是必要的。)

您应该始终检查诸如open().

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


mnd*_*rix 5

有多种方法可以重定向和恢复 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";
Run Code Online (Sandbox Code Playgroud)

使用local

my $out
do {
    local *STDOUT;
    open STDOUT, ">>", \$out;
    print "written to the variable\n";
};
print "written to original STDOUT\n";
Run Code Online (Sandbox Code Playgroud)

享受。