【发布时间】:2014-05-08 14:27:00
【问题描述】:
$ perl5.8 -w -e 'if (my $pid=open(my $P, "|-")) {
kill("SIGKILL",$pid); sleep(2); print $P "test1:$pid\n";}; '
Broken pipe
现在我正试图抓住那根破损的管道
$ 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。
sub 的几乎任何内容都不会产生任何效果(打印、模具、更改包变量值)
代码不会死;如果您最终将某些内容打印到 STDOUT,它将打印。
我错过了什么?
更新:@jm666 的回答让我想到了这个问题:管道的写入没有被刷新;因此,现在获得 SIGPIPE 还为时过早。添加 autoflush 有帮助:
$ 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
$
【问题讨论】:
-
FWIW,使用 Perl 5.16 捕获管道没有问题。我的意思是子被正确执行。顺便问一下操作系统是什么?
-
@i-blis - 我在 Solaris 上的 Perl 5.8 和 Linux 上的 5.8 和 5.12 上尝试过。除非它是我环境中的一些特殊设置,否则它应该排除操作系统特定的问题;不确定 5.12 和 5.16 之间是否存在特定于版本的管道错误
-
你在什么平台上运行?
-
@Borodin - Linux dmesg 是
Linux version 2.6.18-164.9.1.el5PAE (mockbuild@ls20-bc2-13.build.redhat.com) (gcc version 4.1.2 20080704 (Red Hat 4.1.2-46)) #1 SMP Wed Dec 9 03:46:34 EST 2009。如前所述,我尝试了 5.8 和 5.12 Perls -
@Borodin - 我也尝试作为脚本运行(而不是单行);并且作为 bash 和 tsch 一个衬垫,以防我的外壳有一些奇怪的环境