2015-11-20 7 views
0

Этот отличный вопрос How to read to and write from a pipe in Perl? дает отличный ответ.Как читать и писать из трубы в perl с помощью ActiveState Perl?

Он не работает на ActiveState Perl.

клопы раздел perlfork http://docs.activestate.com/activeperl/5.14/lib/pods/perlfork.html говорит

В некоторых случаях на уровне ОС ручки созданы трубы(), гнездо(), и принимают() операторы , по-видимому, не дублируется точно в псевдопроцессах. Это происходит только в некоторых ситуациях: , но там, где это происходит, это может привести к возникновению взаимоблокировок между концами чтения и записи в трубах или невозможностью отправки или получения данных через дескрипторы сокетов.

Непонятно, что означает «не дублируется точно» или если оно даже применяется в этом случае.

Вот тестовая программа

#! /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 как perl для Windows, но я думаю о 'tr' как утилите для Unix-y-систем. – mob

+0

Это скрипт perl для работы на нескольких платформах. ActiveState - это perl, предоставляемый на платформе Windows. 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. 

 Смежные вопросы

  • Нет связанных вопросов^_^