Perl:关闭信号处理程序中的子进程管道挂起?

lem*_*eze 8 linux perl signals pipe alarm

我需要在一个阻止io的脚本上超时.
令人惊讶的是,exit如果有一个打开管道到子进程,它会挂起:

#!/usr/bin/perl                                                                                             
(-f "foo") || die "file foo doesn't exist";
open(IN, "tail -f foo |");

$SIG{ALRM} = sub
{
    print "trying to exit...\n";
    exit 0;     # Hangs with above open() call
};
alarm 1;

while (1)
{   
    sleep 5;   # Do stuff ...
}
Run Code Online (Sandbox Code Playgroud)

没有open调用它可行,不幸的是删除它不是一个选项,在这种情况下脚本需要它.

看起来像是exit试图关闭文件句柄,这就是悬挂:

$SIG{ALRM} = sub
{
    print "trying to close...\n";
    close(IN);            # Hangs ...
    print "ok\n";
    exit 0;
};
Run Code Online (Sandbox Code Playgroud)

我想从信号处理程序中收获孩子并不太高兴...

有没有人知道这方面的好方法?

Mil*_*ler 10

信号处理程序是一个红色鲱鱼,close将阻止,无论如何:

open my $foo, "tail -f foo |" or die "Can't open process: $!";

close $foo;     # <--- will block
Run Code Online (Sandbox Code Playgroud)

解决此问题的一种方法是通过打开捕获子进程ID ,然后杀死该子进程:

my $subprocess = open my $foo, "tail -f foo |" or die "Can't open process: $!";

say "subprocess=$subprocess";

kill 'KILL', $subprocess;

close $foo;     # <--- happy now
Run Code Online (Sandbox Code Playgroud)