SIGINT 未传播到后台子进程

SIGINT 未传播到后台子进程

我需要发送SIGINT以优雅地终止进程,但我不能。

这是一个示例,因为执行发生的环境是“未知”(travis.com 中的 bash 脚本)

通过启动这样的流程,我设法获得(模拟)相同的行为(command &) &

vagrant@host:~$ (sleep 40 &) &
[1] 8473
vagrant@host:~$ ps -o pid,pgid,args
  PID  PGID COMMAND                     
 2787  2787 -bash                       
 8474  8473 sleep 40                    
 8490  8490 ps -o pid,pgid,args  
[1]+  Done                    ( sleep 40 & )
vagrant@host:~$ kill -INT 8474  ##### here I send SIGINT to the process
vagrant@host:~$ kill -INT -8473 ##### here I send SIGINT to the process group
vagrant@host:~$ ps -o pid,pgid,args
  PID  PGID COMMAND                     
 2787  2787 -bash                       
 8474  8473 sleep 40                    
 8559  8559 ps -o pid,pgid,args  

我用谷歌搜索并阅读了很多有关信号和组的内容,但我无法理解这里发生了什么。信号是否在某个时刻被忽略?怎么了?我怎样才能发送SIGINT到该sleep进程?

编辑:如果SIGTERM使用,则进程被杀死(也许父子shell被杀死?)

答案1

为了让非交互式作业响应 SIGINT,您需要为 SIGINT 创建一个处理程序:

$ ( (trap "echo Got SigInt" SIGINT; sleep 60) & ) &
[1] 13619
$ 
[1]+  Done                    ( ( trap "echo Got SigInt" SIGINT; sleep 60 ) & )
$ ps -o pid,pgid,args
  PID  PGID COMMAND
11972 11972 bash
13620 13619 bash
13621 13619 sleep 60
13622 13622 ps -o pid,pgid,args
$ kill -INT 13620
$ kill -INT 13621
$ Got SigInt

向睡眠进程发送 SIGINT

正如 Stéphane Chazelas 在评论中建议的那样,如果目标是返回 SIGINT 的默认行为,我们可以使用trap - SIGINT.例如:

$ ( (trap - SIGINT; sleep 60) & ) &
[1] 16690
$ ps -o pid,pgid,args
  PID  PGID COMMAND
11972 11972 bash
16691 16690 bash
16692 16690 sleep 60
16693 16693 ps -o pid,pgid,args
[1]+  Done                    ( ( trap - SIGINT; sleep 60 ) & )
$ kill -INT 16692
$ ps -o pid,pgid,args
  PID  PGID COMMAND
11972 11972 bash
16698 16698 ps -o pid,pgid,args

相关内容