为什么没有SIGINT被抓到这里?

时间:2010-07-14 15:31:25

标签: linux perl process signals

这是怎么回事?我以为SIGINT会被发送到前台进程组。

(我想,也许,system()正在运行一个shell,为子进程创建一个新的进程组?任何人都可以确认吗?)

% perl
local $SIG{INT} = sub { print "caught signal\n"; };
system('sleep', '10');

然后立即点击ctrl + d然后按ctrl + c,注意“抓住信号”从不打印。

我觉得这是一件简单的事情......无论如何要解决这个问题?问题是当通过系统运行一堆命令导致按住ctrl + c直到所有迭代完成(因为perl永远不会得到SIGINT)并且相当恼人......

如何解决这个问题? (我已经使用fork()直接进行了测试,并了解这是有效的......目前这不是一个可接受的解决方案)

更新:请注意,这与“睡眠”有,只是命令需要花费一些任意长时间才能运行比它周围的perl更多。那么按ctrl + c会被发送到命令(就像它在前台进程组中那样?)并以某种方式设法永远不会被发送到perl。

2 个答案:

答案 0 :(得分:4)

来自perldoc system

  

由于在执行系统期间忽略了SIGINT和SIGQUIT,   如果您希望您的程序在收到这些信号时终止,您需要根据返回值自行安排。

@args = ("command", "arg1", "arg2");
system(@args) == 0
   or die "system @args failed: $?"
     

如果您想手动检查系统故障,可以检查所有可能的故障   模式通过检查$?像这样:

if ($? == -1) {
    print "failed to execute: $!\n";
}
elsif ($? & 127) {
    printf "child died with signal %d, %s coredump\n",
       ($? & 127),  ($? & 128) ? 'with' : 'without';
}
else {
    printf "child exited with value %d\n", $? >> 8;
}
     

或者,您可以使用来自POSIX模块的W *()调用来检查$ {^ CHILD_ERROR_NATIVE}的值

答案 1 :(得分:0)

我不太了解你在这里想要实现的目标......但是你尝试过简单地比较:

perl -wle'local $SIG{INT} = sub { print "caught signal"; }; sleep 10;'

你能解释一下你想要的效果,以及为什么要调用shell?你可以直接调用外部程序而不涉及shell吗?