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

kill -s SIGTERM仅终止父进程和一级子进程的原因及行为疑问

进程递归终止的疑问与解答

实验场景与问题

实验脚本

parent.sh:

#!/bin/bash
/home/oracle/child.sh &
sleep infinity

child.sh:

#!/bin/bash
sleep infinity

启动命令

su oracle -c parent.sh &

进程树

[root@source ~]# ps -ef | grep "/home/oracle"
root     14129  1171  0 12:39 pts/1    00:00:00 su oracle -c /home/oracle/parent.sh
oracle   14130 14129  0 12:39 ?        00:00:00 /bin/bash /home/oracle/parent.sh
oracle   14131 14130  0 12:39 ?        00:00:00 /bin/bash /home/oracle/child.sh

执行kill -s SIGTERM 14129后,进程14129和14130立即终止,但14131长期存活并被重新父化至进程1,由此产生两个疑问:

  1. 若kill命令不会终止子进程,为何发送SIGTERM给14129时14130会被终止?
  2. 若kill命令可终止子进程,为何仅终止一级子进程?该行为是否有保障?

解答

问题1:为何14130会被终止?

kill命令本身不会主动递归终止目标进程的子进程,14130被终止的原因是它是su oracle -c parent.sh(进程14129)的直接子进程,且su进程在收到SIGTERM退出时,会向自己启动的子进程发送终止信号,这是su这类程序的默认实现行为。

具体来说,su oracle -c parent.sh启动后会fork出子进程(14130)执行bash运行parent.sh,当14129收到SIGTERM终止时,会在退出前向14130发送SIGHUP或SIGTERM信号,导致14130随之终止。

问题2:为何仅终止一级子进程,行为是否有保障?

kill命令本身没有递归终止子进程的功能,14131未被终止的核心原因是:parent.sh进程(14130)在收到信号终止时,没有向它的后台子进程14131发送终止信号。

parent.sh用&将child.sh放到后台运行,此时child.sh是它的后台子进程。bash的默认逻辑是收到终止信号时,不会主动向后台子进程发送信号,后台进程会成为孤儿进程,随后被进程1接管并继续存活。

这种“仅终止一级子进程”的行为没有通用性保障:su是否向子进程发信号、bash如何处理后台子进程,都属于程序自身的实现细节,而非kill命令的标准特性。不同版本的su、bash可能有不同处理逻辑,不能依赖该行为实现进程树的完整清理。

如果需要递归终止整个进程树,建议使用专门工具(如pkill -P <PID>),或在父进程中通过trap捕获信号,主动向所有子进程发送终止指令。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 06:10:36