2014-03-28 99 views
3
$ perl5.8 -w -e 'if (my $pid=open(my $P, "|-")) { 
     kill("SIGKILL",$pid); sleep(2); print $P "test1:$pid\n";}; ' 
Broken pipe 

现在,我想抓住那水管坏了为什么我的SIGPIPE不能打印消息?

$ perl5.8 -w -e '$SIG{PIPE} = sub {print "SIGPIPE\n";return 1}; 
    if (my $pid=open(my $P, "|-")) { 
     kill("SIGKILL",$pid); sleep(2); print $P "test1:$pid\n"}; 
$ 

一无所有的时候我本来期望SIGPIPE都被打印出来。看起来好像它把我的匿名子处理程序看作是IGNORE

  • 差不多子不产生任何效果的任何内容(印刷,管芯,封装改变变量值)

  • 代码不会死;如果您打印某些内容到标准输出,则会打印。

我在想什么?


UPDATE:@ jm666的回答使我的问题:管道的写入未冲洗;因此获得SIGPIPE还为时过早。添加自动刷新帮助:

$ perl5.8 -w -e 'use IO::Handle ;$SIG{PIPE} = sub {print "SIGPIPE\n"}; 
    if (my $pid=open(my $P, "|-")) { 
    $P->autoflush(1); 
    kill(SIGTERM,$pid); sleep(2);;print $P "test1:$pid\n"}; ' 

SIGPIPE 
$ 
+0

FWIW,没有问题用Perl 5.16捕捉管。我的意思是子被正确执行。顺便说一句,操作系统是什么? –

+0

@ i-blis - 我在Solaris上使用Perl 5.8并在Linux上使用5.8和5.12。除非在我的环境中有特殊设置,否则应该排除操作系统特定的问题;不确定5.12和5.16之间是否存在版本特定的管道错误 – DVK

+0

您在哪个平台上运行? – Borodin

回答

3

对管道的物理写入延迟,因此您可以在关闭时捕获它们。下一个打印消息。 (添加的close $P

perl -w -e '$SIG{PIPE} = sub {print "SIGPIPE\n";return 1}; if (my $pid=open(my $P, "|-")) { kill("SIGKILL",$pid); sleep(2); print $P "test1:$pid\n";close $P};' 

更多:http://perldoc.perl.org/perlipc.html

+0

哦!让我看看autoflush是否有帮助!它做了!!! – DVK

+0

管道的缺省缓冲模式只是perl版本之间可能发生变化的那种... –

+0

@ WumpusQ.Wumbley - 貌似合理。我太死了,现在不去追逐文件,但不会感到惊讶 – DVK