2012-06-29 162 views
5

我想要做一個主perl腳本調用perl腳本和通過管道進行交互。簡單的open3例子不工作

我寫此代碼爲大師:

#!/usr/bin/env perl 

use strict; 
use warnings; 

use IPC::Open3; 

my @children; 

for my $i (0 .. 4) { 
    print "Master: " . $i . ", I summon you\n"; 

    $children[$i] = {}; 

    $children[$i]->{'pid'} = open3(my $CH_IN, my $CH_OUT, my $CH_ERR, 'perl child.pl -i ' . $i); 

    $children[$i]->{'_STDIN'} = $CH_IN; 
    $children[$i]->{'_STDOUT'} = $CH_OUT; 
    $children[$i]->{'_STDERR'} = $CH_ERR; 

    my $line = readline $children[$i]->{'_STDOUT'}; 
    print $line ; 

} 

print "Master: Go fetch me the sacred crown\n"; 

for my $i (0 .. 4) { 
    $children[$i]->{'_STDIN'}->write("fetch the sacred crown\n"); 
    my $line = readline $children[$i]->{'_STDIN'}; 
    print $line ; 
} 

print "Master: Thanks. Now die!!!\n"; 

for my $i (0 .. 4) { 
    $children[$i]->{'_STDIN'}->write("die !!\n"); 
    my $line = readline $children[$i]->{'_STDIN'}; 
    print $line ; 
} 

這一個孩子:

#!/usr/bin/env perl 

use Getopt::Long ; 

my $cmdline_id ; 

GetOptions ('i=s' => \$cmdline_id) ; 

my $id = $cmdline_id ; 

exit 1 if !defined $id ; 

print "I am $id, and I am awaken\n" ; 

while(<STDIN>) { 
    print STDOUT $id . ': Master ask me to ' . $_ ; 

    if ($_ =~ /exit/oi) { 
     exit 0 ; 
    } 
} 

但是,當我啓動主,他在閱讀從孩子的反應只是掛。

有關我做錯了什麼的想法,爲什麼?

回答

4

你是suffering from buffering

$|=1附近的子進程的開始,以允許孩子打印而無需等待輸出緩衝區填滿。

0

作爲一個方面說明,傳遞第三個參數(因爲你是)沒有做到你想要的。您需要使用Symbol的gensym來初始化變量。

use Symbol qw(gensym); 

my %child; 
$child{pid} = open3(
    $child{'_STDIN' } = gensym, 
    $child{'_STDOUT'} = gensym, 
    $child{'_STDERR'} = gensym, 
    'perl', 'child.pl', '-i' => $i 
); 

$children[$i] = \%child;