问题
I want to redirect STDERR
and STDOUT
to a variable. I did this.
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.
}
The problem with system
. I want the output of this call to be captured too.
回答1:
Are you seeking to capture the output in a variable? If so, you have use backticks or qx{}
with appropriate redirection. For example, you could use:
#/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";
}
(I happen to have programs pth1, pth2 and pth3 in the directory - they were made OK; pth4 and above write errors to stderr; the redirection was necessary.)
You should always check the success of operations such as open()
.
Why is this necessary? Because writing to a variable requires the cooperation of the process doing the writing - and make
doesn't know how to cooperate.
回答2:
use Capture::Tiny!
回答3:
There are several ways to redirect and restore STDOUT. Some of them work with STDERR too. Here are my two favorites:
Using select
:
my $out;
open my $fh, ">>", \$out;
select $fh;
print "written to the variable\n";
select STDOUT;
print "written to original STDOUT\n";
Using local
:
my $out
do {
local *STDOUT;
open STDOUT, ">>", \$out;
print "written to the variable\n";
};
print "written to original STDOUT\n";
Enjoy.
回答4:
The reason this is happening is that the STDOUT and STDERR "filehandles" are not equivalent to stderr and stdout handles provided by the shell to the perl binary. In order to achieve what you want, you should use open instead of system
回答5:
Why not use IPC::Open3
?
来源:https://stackoverflow.com/questions/4415497/how-to-redirect-stdout-and-stderr-to-a-variable