【问题标题】:How to read to and write from a pipe in perl with ActiveState Perl?如何使用 ActiveState Perl 在 perl 中读取和写入管道?
【发布时间】:2015-11-20 22:16:24
【问题描述】:

这个很好的问题 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() 运算符创建的操作系统级句柄 显然没有在伪过程中准确复制。这只发生在某些情况下, 但是在它确实发生的地方,它可能会导致管道的读写端之间出现死锁 句柄,或者无法通过套接字句柄发送或接收数据。

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

这是测试程序

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

【问题讨论】:

  • 什么是操作系统?我通常认为 ActiveState 是 Windows 的 perl,但我认为 tr 是 Unix-y 系统的实用程序。
  • 这是一个可以在多个平台上运行的 perl 脚本。 ActiveState 是 Windows 平台上提供的 perl。 tr 是 perl 内置的,请参阅 perlop。
  • 那么使用exec 来调用perl 内置函数是没有意义的。见 perlfunc。

标签: perl activestate


【解决方案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.

【讨论】:

    猜你喜欢
    • 2012-06-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-29
    • 1970-01-01
    • 1970-01-01
    • 2015-10-28
    • 1970-01-01
    • 2013-07-24
    相关资源
    最近更新 更多