这是怎么回事?我以为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。
答案 0 :(得分:4)
由于在执行系统期间忽略了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吗?