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

问题描述 投票:0回答:5

我想将

STDERR
STDOUT
重定向到变量。我就是这么做的。

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
的问题。我也希望捕获此调用的输出。

perl system stdout stderr redirect
5个回答
14
投票

使用Capture::Tiny


6
投票

您是否想要捕获变量中的输出?如果是这样,您可以使用反引号或

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 - 它们都正常;pth4 及以上将错误写入 stderr;重定向是必要的。)

您应该经常检查

open()
等操作是否成功。

为什么这是必要的?因为写入变量需要写入过程的合作 - 而

make
不知道如何合作。


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";

使用

local

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

享受吧。


1
投票

为什么不

use IPC::Open3


1
投票

TLDR 答案

use Capture::Tiny;

合并 STDOUT 和 STDERR

如果您希望合并

STDOUT
(来自
print()
)和
STDERR
(来自
warn()
),请使用...

my ($merged,  @result) = capture_merged { print "Hello, world!" };  # static code
my ($merged,  @result) = capture_merged { eval $codetoeval };       # code in variable

分离的 STDOUT 和 STDERR

如果你想让他们分开......

my ($stdout, $stderr, @result) = capture { print "Hello, world!" };   # static code
my ($stdout, $stderr, @result) = capture { eval $codetoeval };        # code in variable

评估结果

@result
表示成功,成功为
[1]
,失败为
[]
。 Tiny 有大量其他功能,您可以查看其他情况,例如代码引用等。但我认为上面的代码应该涵盖大多数 Perl 开发人员的需求。

© www.soinside.com 2019 - 2024. All rights reserved.