我试图通过perlipc文档中看到的东西来解决问题.
如果你正在写一个管道,你也应该陷入SIGPIPE.否则,想一想当你启动一个不存在的命令时会发生什么:open()很可能会成功(它只反映fork()的成功),但是你的输出会失败 - -spectacularly.Perl无法知道命令是否有效,因为您的命令实际上是在exec()可能失败的单独进程中运行的.因此,虽然伪造命令的读者只返回文件的快速结束,但伪造命令的编写者将触发他们最好准备处理的信号.考虑:
open(FH, "|bogus") or die "can't fork: $!";
print FH "bang\n" or die "can't write: $!";
close FH or die "can't close: $!";
Run Code Online (Sandbox Code Playgroud)
直到收盘时才会爆炸,并且它会以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=$?";
Run Code Online (Sandbox Code Playgroud)
如果我正确地阅读它,它说第一个版本可能不会在最后关闭之前死掉.
但是,我的OS X盒子上没有发生这种情况(Perl版本5.8.9到5.15.9).open无论我是否有$ SIG {PIPE}行,它都会在"无法分叉:没有这样的文件或目录" 上爆炸.
我有什么误会?
小智 4
这是在 5.6 开发期间实施的更改,以便 system() 可以检测何时无法分叉/执行子进程
https://github.com/mirrors/perl/commit/d5a9bfb0fc8643b1208bad4f15e3c88ef46b4160
它还记录在http://search.cpan.org/dist/perl/pod/perlopentut.pod#Pipe_Opens
它本身指向 perlipc,但 perlipc 似乎确实缺少这个