【发布时间】: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