STDOUT重定向到变量不捕获管道输出(STDOUT redirected to variable not catching pipe output)

编程入门 行业动态 更新时间:2024-10-11 21:28:56
STDOUT重定向到变量不捕获管道输出(STDOUT redirected to variable not catching pipe output)

我想暂时将stdout重定向到内存变量。 打印正确地重定向到我的变量但不是管道的输出(在我的示例中为bc)。 到底是怎么回事?

#!/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

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

Actual ouput will be:

before bc

Expected output:

before bc 4

最满意答案

这不可能。

管道打开和system调用的标准输出被写入文件描述符1.通常,Perl的STDOUT文件句柄与文件描述符1相关联,但可以对其进行操作。

在此示例中, system调用写入STDOUT文件句柄,该文件句柄写入文件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文件句柄。

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 ,您将(通常可能依赖于操作系统)获得负数。

open STDOUT, '>', \$scalar; print STDERR fileno(STDOUT); # -1

管道打开并且系统调用将无法写入此文件句柄。

您将需要更复杂的解决方法,例如将管道打开输出写入文件,然后将该文件复制到内存中变量中。

This is ... not possible.

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.

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"

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"

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.

更多推荐

本文发布于:2023-07-23 02:29:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1226448.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:变量   管道   重定向   STDOUT   redirected

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!