Cette excellente question How to read to and write from a pipe in Perl? fournit une excellente réponse.Comment lire et écrire depuis un tube en Perl avec ActiveState Perl?
Cela ne fonctionne pas sur ActiveState Perl.
La section BUGS de perlfork http://docs.activestate.com/activeperl/5.14/lib/pods/perlfork.html dit
Dans certains cas, le système d'exploitation au niveau handles par la conduite(), socket() et accept() les opérateurs sont apparemment pas dupliquées avec précision dans les pseudo-processus. Cela ne se produit que dans certaines situations, mais là où cela se produit, il peut en résulter des interblocages entre les extrémités de lecture et d'écriture des poignées ou l'impossibilité d'envoyer ou de recevoir des données entre les poignées de socket.
On ne sait pas exactement ce que signifie «non dupliqué avec précision» ou s'il s'applique même dans ce cas.
Voici le programme de test
#! /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: $!";
Quel est le système d'exploitation? Je pense généralement à ActiveState en tant que perl pour Windows, mais je pense à 'tr' comme un utilitaire pour les systèmes Unix-y. – mob
C'est un script Perl à exécuter sur plusieurs plates-formes. ActiveState est le perl fourni sur la plate-forme Windows. tr est un perl intégré, voir perlop. – codeDr
Ensuite, cela n'a pas de sens d'utiliser 'exec' pour invoquer un perl intégré. Voir perlfunc. – mob