系统子程序和INT信号问题

时间:2011-04-27 15:25:01

标签: perl

我的Perl脚本中有一个INT信号处理程序。当Perl脚本处于系统调用中时发送INT时不会执行它。为什么呢?

考虑:

$ perl5.12/bin/perl -E "$(cat <<EOF

    \$SIG{INT} = sub {say q(trapped INT); exit};
    say q(sleeping ...);
    system q(sleep 10000); # INT at this point is not caught by Perl.

EOF)"
sleeping ...

但是,如果我用睡眠呼叫替换系统调用,它会按预期工作:

$ perl5.12/bin/perl -E "$(cat <<EOF

    \$SIG{INT} = sub {say q(trapped INT); exit};
    say q(sleeping ...);
    sleep 10000; # replaces the system call from above

EOF)"
sleeping ...
trapped INT

Perl版本是:

$ perl5.12/bin/perl -v

This is perl 5, version 12, subversion 3 (v5.12.3) built for x86_64-linux-thread-multi
(with 9 registered patches, see perl -V for more detail)

Copyright 1987-2010, Larry Wall

Binary build 1204 [294330] provided by ActiveState http://www.ActiveState.com
Built Feb  9 2011 14:48:47
...

2 个答案:

答案 0 :(得分:6)

您可以通过选中$?来检测system()子流程是否被SIGINT杀死,如下所示:

use POSIX qw(SIGINT);

sub interrupt {
    say "trapped INT";
    exit;
}

$SIG{INT} = \&interrupt;

say "sleeping";
system ("sleep 100");

if (($? & 127) == SIGINT) {
        interrupt();
} elsif ($?) {
        say "subprocess failed, status $?";
}

外部命令运行时,perl会忽略INTQUIT信号,请参阅system()

答案 1 :(得分:1)

当调用system()时,正在执行的任何内容都控制终端。通过键盘控制向其发送任何信号将被发送到正在执行的进程(在这种情况下是系统的睡眠命令)。

在Perl脚本中捕获信号并使用它们执行某些操作仅在该脚本运行时有效。要在Bash中使用陷阱,您可以使用trap "command" signal

$ perl -e'system("trap \"echo Trapped\" SIGINT; sleep 10");'
^CTrapped