2013-08-18 6 views
9

execed子プロセスからのSTDOUT/STDERRをPerlのパイプ経由で親プロセスに戻そうとしています。私がやりたいと思っていることに最も近いのは、次の場所です。 http://forums.devshed.com/perl-programming-6/exec-and-redirecting-stdout-stderr-168501.htmlexecdedプロセスからstdin/stdoutを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

ファイル記述子を割り当てだけでリダイレクトすることはできません。むしろ、perldoc -f openに記載されているような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, '-|'はほとんどすべての設定作業を行います。親プロセスがREADERで読み取ることができるパイプに、STDOUTという子プロセスを作成します。その場合、手動で行うリダイレクトは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

このコードは、子プロセスからの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) ; 

}

関連する問題