STDOUT重定向到变量,无法捕获管道输出 [英] STDOUT redirected to variable not catching pipe output

查看:95
本文介绍了STDOUT重定向到变量,无法捕获管道输出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆