2014-03-28 97 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