[英]redirecting stdin/stdout from exec'ed process to pipe in Perl
I am trying to have STDOUT/STDERR from a exec'ed child process go back to the parent via a pipe in Perl. 我试图让一个exec的子进程的STDOUT / STDERR通过Perl中的管道返回到父进程。 The closest I have seen to what I want to do is at : http://forums.devshed.com/perl-programming-6/exec-and-redirecting-stdout-stderr-168501.html
我所看到的最接近我想做的是: http : //forums.devshed.com/perl-programming-6/exec-and-redirecting-stdout-stderr-168501.html
The following is a stripped down example of what I am trying to do. 以下是我想要做的事情的简要示例。 I also tried a variant of the link above.
我也试过上面链接的一个变种。 I can't see what I'm doing wrong...
我看不出我做错了什么......
#!/usr/bin/env perl
use strict ;
use warnings ;
my $cmd = "/usr/bin/who -a" ; # anything to stdout
pipe( READER, WRITER ) ;
my $child = fork() ;
if ( $child ) {
print "I am the parent: My pid = $$ junior = $child\n" ;
close( WRITER ) ;
my @output = <READER> ;
print @output ;
print "parent is DONE\n" ;
} else {
print "I am the child. My pid = $$\n" ;
close( READER ) ;
close( STDOUT );
close( STDERR );
*STDOUT = *WRITER ;
*STDERR = *WRITER ;
print WRITER "XXX ouput before exec....\n" ;
exec( $cmd ) or exit(1) ;
}
It's not possible to redirect file descriptors just with assignments. 仅使用赋值重定向文件描述符是不可能的。 Rather one needs to use
open
like described in perldoc -f open
. 而是一个需要使用
open
像中描述perldoc -f open
。 In your case the child code would look like this: 在您的情况下,子代码将如下所示:
print "I am the child. My pid = $$\n" ;
close( READER ) ;
open STDOUT, ">&", \*WRITER or die $!;
open STDERR, ">&", \*WRITER or die $!;
print WRITER "XXX ouput before exec....\n" ;
exec( $cmd ) or exit(1) ;
Slaven Rezic has the right answer to why your code doesn't work, but you should also be aware of a shortcut that you can use. Slaven Rezic对你的代码无效的原因有正确的答案,但你也应该知道你可以使用的快捷方式。 The special pipe+fork
open READER, '-|'
特殊管+叉
open READER, '-|'
does almost all the setup work for you, creating a child process with its STDOUT
writing into a pipe that the parent can read with READER
. 几乎所有的设置都适合你,创建一个子进程,其
STDOUT
写入一个父可以用READER
读取的管道。 That just leaves the STDERR
redirection for you to do manually. 这只是让
STDERR
重定向让你手动完成。
The shortened version of the code looks like this: 缩短版本的代码如下所示:
my $child = open READER, '-|';
defined $child or die "pipe/fork: $!\n";
if ( $child ) {
print "I am the parent: My pid = $$ junior = $child\n" ;
my @output = <READER> ;
print @output ;
print "parent is DONE\n" ;
} else {
print "I am the child. My pid = $$\n" ;
open STDERR, '>&STDOUT';
print "XXX ouput before exec....\n" ;
exec( $cmd ) or exit(1) ;
}
This code is another way to pipe the STDOUT and STDERR from the child process. 此代码是从子进程管道STDOUT和STDERR的另一种方法。
#!/usr/bin/env perl
use strict ;
use warnings;
my $cmd = "/usr/bin/who -a" ; # anything to stdout
pipe( READER, WRITER ) ;
my $child = fork() ;
if ( $child ) {
print "I am the parent: My pid = $$ junior = $child\n" ;
close( WRITER ) ;
my @output = <READER> ;
print @output ;
print "parent is DONE\n" ;
} else {
print "I am the child. My pid = $$\n" ;
close( READER ) ;
open(STDERR,">&", WRITER) or die "Cannot duplicate STDERR;
open(STDOUT,">&", WRITER) or die "cannot duplicate STDOUT";
print WRITER "XXX ouput before exec....\n" ;
exec( $cmd ) or exit(1) ;
} }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.