2013-08-18 73 views
9

我试图通过一个执行过的子进程使STDOUT/STDERR通过Perl中的管道回到父节点。我看到的最接近我想要做的是: http://forums.devshed.com/perl-programming-6/exec-and-redirecting-stdout-stderr-168501.html将执行过程的标准输入/标准输出重定向到Perl中的管道

以下是我尝试去做的一个简单例子。我也尝试了上述链接的变体。我看不到我在做什么错...

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

您可能感兴趣的[IPC :: Open2(http://perldoc.perl.org/IPC/Open2.html)。 – squiguy

回答

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

斯拉文Rezic有正确的答案,为什么你的代码不能正常工作,但你也应该知道一个快捷方式,你可以使用的。特殊管道+叉子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) ; 
} 
0

此代码是另一种方式来管,从子进程输出和错误。

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

}

相关问题