将stdin / stdout从exec'ed进程重定向到Perl中的pipe

时间:2013-08-18 02:54:07

标签: perl redirect exec pipe stdout

我试图让一个执行子进程的STDOUT / STDERR通过Perl中的管道返回到父进程。我所看到的最接近我想做的是: http://forums.devshed.com/perl-programming-6/exec-and-redirecting-stdout-stderr-168501.html

以下是我要做的事情的简要示例。我也试过上面链接的一个变种。我看不出我做错了什么......

#!/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) ;
}

3 个答案:

答案 0 :(得分:5)

仅使用分配重定向文件描述符是不可能的。相反,需要使用open中描述的perldoc -f open。在您的情况下,子代码将如下所示:

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

答案 1 :(得分:4)

Slaven Rezic对您的代码无效的原因有正确的答案,但您也应该了解可以使用的快捷方式。特殊管道+ fork open READER, '-|'几乎可以完成所有设置工作,创建一个子进程,其STDOUT写入父管可以用READER读取的管道。只需离开STDERR重定向即可手动完成。

代码的缩短版本如下所示:

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) ;
}

答案 2 :(得分:0)

此代码是从子进程管道STDOUT和STDERR的另一种方法。

127

}