2013-08-18 72 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) ; 

}

相關問題