如何使用ActiveState Perl读取和写入perl中的管道?

时间:2015-11-20 22:16:24

标签: perl activestate

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

它不适用于ActiveState Perl。

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

  

在某些情况下,由pipe(),socket()和accept()运算符创建的OS级句柄   在伪过程中显然没有准确复制。这只发生在某些情况下,   但它确实发生的地方,可能会导致管道读写端的死锁   处理或无法跨套接字句柄发送或接收数据。

目前尚不清楚“没有准确复制”的含义,或者在这种情况下是否适用。

这是测试程序

#! /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 个答案:

答案 0 :(得分: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.