【发布时间】:2020-07-29 22:54:32
【问题描述】:
我已经阅读了有关 open、close 和 IPC 的所有 perl 文档,并阅读了许多相关的论坛主题,但仍然无法弄清楚我做错了什么。首先,我创建了这个简单的分叉进程来证明我正确地进行了打开处理:
#!/usr/bin/perl
use IO::Handle;
my $pid = open(CHILD, "|-");
if ($pid == 0) {
# child:
while (<STDIN>) { # keeps reading until parent closes it's end of the pipe
chomp $_;
print "child: $_\n";
}
}
else {
# parent:
for my $line (1..3) {
print CHILD "$line\n";
}
my $success = close CHILD;
print "parent: success: $success, \$!: $!, \$?: $?\n";
}
正如预期的那样,输出是:
child: 1
child: 2
child: 3
parent: success: 1, $!: Illegal seek, $?: 0
成功值为真;所以我只是忽略了“非法寻求”,因为它不相关,据说。但是,当我将 STDOUT 别名为管道(以避免需要显式打印到 CHILD)然后将 STDOUT 恢复为其原始值时,如下所示,关闭的 CHILD 不再起作用(即使 STDOUT 不再指向它) :
#!/usr/bin/perl
use IO::Handle;
my $pid = open(CHILD, "|-");
if ($pid == 0) {
# child:
while (<STDIN>) { # keeps reading until parent closes it's end of the pipe
chomp $_;
print "child: $_\n";
}
}
else {
# parent:
open(ORIG_STDOUT, ">&STDOUT") or die "Unable to dup STDOUT: $!";
open(STDOUT, ">&=CHILD") or die "Unable to alias CHILD: $!";
for my $line (1..3) {
print "$line\n";
}
open(STDOUT, ">&=ORIG_STDOUT") or die "Unable to alias ORIG_STDOUT: $!";
my $success = close CHILD;
print "parent: success: $success, \$!: $!, \$?: $?\n";
}
输出是这样的:
child: 1
child: 2
child: 3
parent: success: , $!: Illegal seek, $?: -1
success 值不再为 true,这意味着关闭管道时出错,或者 CHILD 返回了一个非零值。 $ 的 -1 值?表示等待系统调用由于某种原因失败,我不确定“非法搜索”是什么意思,但事实是 $!不为零,进一步表明不仅仅是 CHILD 进程返回一个非零代码使关闭 CHILD 返回错误,而是关闭过程中存在某种错误。我在这里错过了什么?
【问题讨论】:
-
CHILD 是特殊的,因为它还充当孩子的句柄。使用
>&=似乎把事情搞砸了。复制句柄 (>&) 而不是复制其 fd (>&=) 作品