2015-11-20 129 views
0

這個優秀的問題 How to read to and write from a pipe in Perl? 提供了一個很好的答案。如何使用ActiveState Perl在perl中讀取和寫入管道?

它不適用於ActiveState Perl。

perlfork http://docs.activestate.com/activeperl/5.14/lib/pods/perlfork.html 的BUGS部分說

在某些情況下,操作系統級處理由管(),插座()創建的,並接受()運算 顯然不能準確地複製在僞進程中。這隻發生在某些情況下,但在發生這種情況時,可能會導致管道 句柄的讀取和寫入結束之間出現死鎖,或者無法通過套接字句柄發送或接收數據。

目前還不清楚「未準確重複」的含義或者它是否適用於這種情況。

下面是測試程序

#! /usr/bin/env perl 

use strict; 
use warnings; 

my $isActiveStatePerl = 1 ; # defined(&Win32::BuildNumber); 

sub pipeFromFork 
{ 
    return open($_[0], "-|") if (!$isActiveStatePerl); 
    pipe $_[0], my $child or die "cannot create pipe"; 

    printf STDERR "$$: pipe create parent %d child %d\n", fileno($_[0]), fileno($child); 
    my $pid = fork(); 
    die "fork failed: $!" unless defined $pid; 
    if ($pid) {   # parent 
     printf STDERR "$$: fork parent close child %d\n", fileno($child); 
     close $child; 
    } else {   # child 
     open(STDOUT, ">&=", $child) or die "cannot clone child to STDOUT"; 
     printf STDERR "$$: fork child close parent %d stdout %d\n", fileno($_[0]), fileno(STDOUT); 
     close $_[0]; 
    } 
    return $pid; 
} 


my @transform = qw(tr [A-Za-z] [N-ZA-Mn-za-m]); # rot13 
my @inception = (
    "V xabj, Qnq. Lbh jrer qvfnccbvagrq gung V pbhyqa'g or lbh.", 
    "V jnf qvfnccbvagrq gung lbh gevrq.", 
); 

sub snow_fortress { print STDERR "$$: 1 start\n"; print map "$_\n", @inception } 

sub hotel 
{ 
    printf STDERR "$$: 2 start %d\n", fileno(STDIN); 
    # my $pid = open STDIN, "-|"; 
    my $fh; 
    my $pid = pipeFromFork($fh); 
    print STDERR "$$: hotel: pid $pid\n"; 
    defined($pid) or die "$0: fork: $!"; 
    if (0 == $pid) { 
     snow_fortress; 
     print STDERR "$$: 1 exit\n"; 
     exit(0); 
    } 
    open(STDIN, "<&", $fh) or die "cannot clone to STDIN"; 
    printf STDERR "$$: 2 exec %d\n", fileno(STDIN); 
    # print while <STDIN>; 
    exec @transform or die "$0: exec: $!"; 
} 

# my $pid = open my $fh, "-|"; 
my $pid = pipeFromFork(my $fh); 
defined($pid) or die "$0: fork: $!"; 
print STDERR "$$: outer: pid $pid\n"; 

if (0 == $pid) { 
    hotel; 
    print STDERR "$$: 2 exit\n"; 
    exit(0); 
} 

print STDERR "$$: 3 start " . fileno($fh) . "x\n"; 

print while <$fh>; 
print STDERR "$$: 3 end\n"; 
close $fh or warn "$0: close: $!"; 
+1

什麼操作系統?我通常認爲ActiveState是Windows的perl,但我認爲'tr'作爲Unix-y系統的一個工具。 – mob

+0

這是一個在多個平臺上運行的perl腳本。 ActiveState是Windows平臺上提供的perl。 tr是perl內建的,參見perlop。 – codeDr

+1

然後,使用'exec'來調用perl內建是沒有意義的。見perlfunc。 – mob

回答

0

選項1

- 如果輸入perl的過程是很簡單的放進一個內膽

my $cmd = "perl -e ' -- your simple perl -- ' | cmdToExecute"; 

my $out; 
open my $cmdpipe "-|", $cmd; 
while (<$cmdpipe>) { 
    $out .= $_; 
} 

# $out is your captured output 

- 如果你的輸入perl進程很複雜,把它放到一個文件中

my $cmd = "perl compInput.pl | cmdToExecute"; 
# rest as above 

選項2

- remove ActiveState perl 
- install git for windows and use the perl from it.