有时,向某个进程发送 SIGTERM 会导致该进程向其所有子进程发送 SIGTERM。但是,有时这种方法不起作用。
是否有命令或实用程序允许我同时终止一个进程及其所有子进程?我通常会手动将所有 pid 收集到一个 kill 命令中,但感觉很愚蠢。
这个问题询问如何使用 perl 来完成此操作,但任何可以完成这项工作的方法都很棒。
答案1
这那么问题来了涵盖了这一点。
答案2
假设进程共享一个会话标识符(除非它们明确调用了 setsid(),否则它们应该共享该标识符),您可以使用 pkill 按会话杀死它们:
user@machine:~> ps -o pid,sess,cmd -U user
PID SESS CMD
12804 12804 -bash
12916 12804 ps -o pid,sess,cmd -U user
user@machine:~> sh
sh-3.00$ sh
sh-3.00$ sh
sh-3.00$ sh
sh-3.00$ sh
sh-3.00$ sh
sh-3.00$ ps -o pid,sess,cmd -U user
PID SESS CMD
12804 12804 -bash
12920 12804 sh
12921 12804 sh
12922 12804 sh
12924 12804 sh
12926 12804 sh
12928 12804 sh
12937 12804 ps -o pid,sess,cmd -U user
sh-3.00$
如果从另一个终端我这样做:
pkill -9 -s 12804
然后一切都会一下子消亡。
您也可以按进程组进行终止,不过这对于许多都低于父进程一个级别的子进程(而不是相关进程链)来说更有用。
答案3
通常,响应的客户端应收到信号并自行关闭,从而终止其派生的所有子进程。另一方面,如果客户端没有响应,则正常的终止信号可能不会引起任何响应。
因此,您接下来要发送一个 SIGKILL,它告诉系统本身让该进程立即停止 - 大多数情况下它可以这样做,除非进程处于不可中断的睡眠状态,例如等待某些 I/O 输入或类似情况。
在这种情况下,即使 SIGKILL 最终也不会对进程产生任何影响;子进程可能会处于类似的迟缓状态。
有一种边界情况,即父进程可能会顺利终止,但子进程无法终止。然后,您将得到一个僵尸进程,由于其父进程已经消失,因此无法清理,但它没有响应任何操作。摆脱这些进程的唯一方法是重新启动;但在大多数情况下,它们是无害的,因为它们唯一做的事情就是占用 PID,而它们尝试使用的任何套接字都已经消失。
答案4
如果我想杀死 Firefox 的进程树,那么是否可以通过上述命令“pkill -9 -s firefox”来杀死它