0

这个很好的问题 How to read to and write from a pipe in Perl? 提供了一个很好的答案。

它不适用于 ActiveState Perl。

perlfork http://docs.activestate.com/activeperl/5.14/lib/pods/perlfork.html的错误部分 说

在某些情况下,由 pipe()、socket() 和 accept() 运算符创建的操作系统级别的句柄显然不会在伪进程中准确复制。这仅在某些情况下发生,但在确实发生的情况下,可能会导致管道句柄的读写端之间出现死锁,或者无法跨套接字句柄发送或接收数据。

目前尚不清楚“未准确复制”是什么意思,或者它是否适用于这种情况。

这是测试程序

#! /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: $!";
4

1 回答 1

1

选项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.
于 2015-11-25T03:03:01.490 回答