我想将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
的问题。我也希望捕获此调用的输出。
答案 0 :(得分:13)
答案 1 :(得分:4)
您是否想要在变量中捕获输出?如果是这样,您可以使用反引号或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
不知道如何合作。
答案 2 :(得分:3)
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";
享受。
答案 3 :(得分:2)
发生这种情况的原因是STDOUT和STDERR“文件句柄”不等同于shell提供给perl二进制文件的stderr和stdout句柄。为了达到您的目的,您应该使用open代替system
答案 4 :(得分:1)
为什么不use IPC::Open3
?
答案 5 :(得分:0)
如果您希望合并 STDOUT
(来自 print()
s)和 STDERR
(来自 warn()
s),请使用...
my ($merged, @result) = capture_merged { print "Hello, world!" }; # static code
my ($merged, @result) = capture_merged { eval $codetoeval }; # code in variable
如果你想让它们分开...
my ($stdout, $stderr, @result) = capture { print "Hello, world!" }; # static code
my ($stdout, $stderr, @result) = capture { eval $codetoeval }; # code in variable
@result
表示成功,成功为[1]
,失败为[]
。 Tiny 有大量其他功能,您可以查看其他情况,例如代码引用等。但我认为上面的代码应该可以满足任何 Perl 开发人员的大部分需求。