我正试图通过我在perlipc文档中看到的内容进行拼图。
如果你正在写一个管道,你也应该陷入SIGPIPE。除此以外, 想想当你启动一个命令管道时会发生什么 不存在:open()很可能会成功(只有 反映了fork()的成功,但随后你的输出会 失败 - 壮观。 Perl无法知道该命令是否有效 因为你的命令实际上是在一个单独的进程中运行的 exec()可能失败了。因此,虽然是虚假命令的读者 返回只是一个快速结束的文件,编写器将以bogus命令触发 他们最好准备好处理的信号。考虑:
open(FH, "|bogus") or die "can't fork: $!";
print FH "bang\n" or die "can't write: $!";
close FH or die "can't close: $!";
直到收盘时才会爆炸,它会爆炸 SIGPIPE。要抓住它,你可以使用它:
$SIG{PIPE} = 'IGNORE';
open(FH, "|bogus") or die "can't fork: $!";
print FH "bang\n" or die "can't write: $!";
close FH or die "can't close: status=$?";
如果我正确阅读,它说第一个版本可能不会在最后结束前消失。
但是,我的OS X盒子上没有发生这种情况(Perl版本5.8.9到5.15.9)。无论我是否有$ SIG {PIPE}行,它都会在open
上以“无法分叉:没有这样的文件或目录”爆炸。
我误解了什么?
答案 0 :(得分:3)
这是在5.6开发期间实现的更改,以便system()可以检测到何时无法分叉/执行孩子
https://github.com/mirrors/perl/commit/d5a9bfb0fc8643b1208bad4f15e3c88ef46b4160
http://search.cpan.org/dist/perl/pod/perlopentut.pod#Pipe_Opens
中也记录了这一点它本身指向perlipc,但perlipc似乎缺少这个
答案 1 :(得分:0)
我的Perl上的输出相同,v5.14.2
,Ubuntu 12.04:
$ perl
open(FH, "|bogus") or die "can't fork: $!";
print FH "bang\n" or die "can't write: $!";
close FH or die "can't close: $!";
can't fork: No such file or directory at - line 1.
而且该错误是奇数,因为它与分叉无关 - 它们必须添加一些前瞻性猜测以查看它是否可以执行bogus
。 (最好是竞争条件,但在常见情况下可能会提供明显更好的错误处理;并且只有在比赛失败时与旧行为一样不方便。)