终止一系列进程的最可靠方法

The most reliable way to terminate a family of processes

终止 Linux 中的一系列进程的最佳方法是什么,如果我们假设:

  1. 家族中的任意进程可能会在我们开始清理之前被杀死/终止;因此,如果子进程不终止,它们的 PPID 将为 1
  2. 进程可以改变进程组

我正在查看的特定场景是 Bash,但技术越通用越好。

您可能希望在不同的登录 shell 中执行杀戮(最终通过脚本),以确保您不会不小心 stopping/killing 正 shell/script 尝试执行在它完成它的工作之前进行整体杀戮:)

第一个关键策略是不直接终止进程,而是:

一旦基于 ppid 的整个祖先树被冻结,你就可以开始定位和冻结基于进程组的祖先——你仍然可以可靠地确定这些进程组,只要 parents 进程改变了它们进程组仍然存在(因为它们的 ppid 未更改)- 将这些组添加到 pgids 列表中以进行 nuked 并冻结任何新的 ppid-based 进程子树,您可能会在上面的这些组中找到:

  • 如果他们的 parents 还活着,他们应该已经被冻结了 他们在冰冻的 ppid-based 祖先树中
  • 如果他们是孤儿,他们将在整个 pgid 被核毁时被杀死

可以通过会话 ID 以非常类似于基于组 ID 的方式发现相关进程(除了 kill cmd 支持组 ID 但不支持会话 ID,因此需要通过 pid 完成杀戮)。 =13=]

另一种查找潜在相关进程的方法是通过他们的 tty,如果他们有的话。但要小心——它们可能不是你想要杀死的进程的后代,而是祖先或兄弟姐妹。您仍然可以在调查时冻结通过这种方式找到的 ppid-based 子树和组 - 如果不需要杀死它们,您以后总是可以 "thaw" 它们(使用 kill -CONT)。

如果 parents 死亡并且没有 pty,我不知道如何定位被声明自己为会话领导者的进程解耦的后代进程子树(因此更改它们的 sid 和 pgid)。

一旦整个子树列表被冻结,进程就可以被终止(根据需要通过 pid 或 pgid)或解冻以继续它们的工作。