You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

向后台进程发送SIGINT无法终止的原因及正确终止方法

问题原因及解决方法

为什么kill -INT 27717无效?

当你通过sh -c "work.sh &"把进程放到后台执行时,bash会自动将该后台进程的SIGINT和SIGQUIT信号设置为忽略状态——这是终端会话的默认保护机制,目的是避免前台按Ctrl+C时误杀后台运行的任务。

你发送的SIGINT信号确实到达了work.sh进程,但由于它的SIGINT处理被设为忽略,所以不会触发你定义的sigint_handler函数,进程自然会继续运行。

正确终止的方法

方法一:给整个进程组发送SIGINT

work.sh在循环中会启动sleep子进程,二者属于同一个进程组。给整个进程组发信号,既能触发work.sh的信号处理,又能直接终止sleep(否则sleep会运行到结束后,work.sh才会回到循环检查状态):

  1. 获取work.sh的进程组ID(PGID,通常和PID相同):
    ps -o pgid= 27717
    
  2. 给进程组发送SIGINT:
    kill -INT -<PGID>
    
    比如PGID是27717,执行kill -INT -27717即可。

方法二:调至前台后按Ctrl+C

如果允许交互操作,直接把后台进程拉到前台,再用常规的Ctrl+C即可:

  1. 用jobs查看后台作业号:
    jobs
    
    输出类似[1]+ Running work.sh &,其中1是作业号。
  2. 将作业调至前台:
    fg %1
    
  3. 按下Ctrl+C,进程会按脚本逻辑触发SIGINT并终止。

方法三:修改启动方式,让进程响应SIGINT

如果需要后台进程启动后就能直接响应SIGINT,可以用setsid创建独立会话,避免继承父shell的信号忽略设置:

setsid work.sh &

之后直接执行kill -INT <PID>就能触发sigint_handler并终止进程。

内容的提问来源于stack exchange,提问作者Alex Belous

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 06:05:11