STDOUT重定向到变量,无法捕获管道输出 [英] STDOUT redirected to variable not catching pipe output
问题描述
我想将stdout临时重定向到内存中的变量.打印正确地重定向到我的变量,而不是管道的输出(在我的示例中为bc).到底是怎么回事?
I want to temporarily redirect stdout to an in memory variable. Prints are correctly redirected to my variable but not the output of a pipe (bc in my example). What is going on?
#!/usr/bin/perl
my $stdout_sink;
open(my $orig_stdout, ">&STDOUT") || die $!;
close STDOUT;
open(STDOUT, ">", \$stdout_sink) || die $!;
# produce some output in different ways
print "before bc\n"; # ok
open my $fh, "| bc";
print $fh "2+2\n"; # not ok
close $fh;
close STDOUT;
open(STDOUT, ">&", $orig_stdout) || die $!;
print "$stdout_sink";
实际输出将为:
before bc
预期输出:
before bc
4
推荐答案
这是不可能的.
管道打开的标准输出和system
调用被写入文件描述符1.通常,Perl的STDOUT
文件句柄与文件描述符1相关联,但是可以对其进行操作.
Standard output of piped opens and system
calls are written to file descriptor 1. Normally, Perl's STDOUT
file handle is associated with file descriptor 1, but that can be manipulated.
在此示例中,system
调用写入STDOUT
文件句柄,该句柄写入文件foo
.
In this example, the system
calls writes to STDOUT
filehandle, which writes to the file foo
.
close STDOUT; # closes file descriptor 1
open STDOUT, '>', 'foo'; # reopens STDOUT as file descriptor 1
system("echo bar");
close STDOUT;
print STDERR "foo: ",`cat foo`;
# result: "foo: bar"
但是在此示例中,system
调用将写入BAZ
文件句柄.
But in this example, the system
calls writes to the BAZ
filehandle.
close STDOUT; # closes file descriptor 1
open BAZ, '>', 'baz'; # attaches fd 1 to handle BAZ
open STDOUT, '>', 'foo'; # opens new file descriptor, maybe fd 3
system("echo bar");
close STDOUT;
print STDERR "foo: ",`cat foo`;
print STDERR "baz: ",`cat baz`;
# result: "foo: baz: bar"
内存中的文件句柄不是真实的文件句柄.如果在其上调用fileno
,则(通常,可能取决于操作系统)将得到一个负数.
An in-memory filehandle is not a real filehandle. If you call fileno
on it, you will (generally, may be OS dependent) get a negative number.
open STDOUT, '>', \$scalar;
print STDERR fileno(STDOUT); # -1
打开的管道已打开,系统调用将无法写入此文件句柄.
Piped opens and system calls will not be able to write to this filehandle.
您将需要更复杂的解决方法,例如将通过管道打开的输出写入文件,然后将该文件复制到内存变量中.
You will need a more complicated workaround, like writing the piped open output to a file, and then copying that file into the in-memory variable.
这篇关于STDOUT重定向到变量,无法捕获管道输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!