如何在中断时杀死当前shell的所有子节点?

时间:2011-06-08 19:53:21

标签: shell configuration posix

我的脚本cdist-deploy-to和cdist-mass-deploy(来自cdist配置管理)以交互方式运行(即由用户调用)。

这些脚本调用了很多脚本,这些脚本再次调用了一些脚本:

cdist-mass-deploy ...
   cdist-deploy-to ...
       cdist-explorer-run-global ...
           cdist-dir ....

我想要的是退出/终止所有脚本,只要cdist-mass-deploy由控制C(SIGINT)停止或使用SIGTERM终止。

cdist-deploy-to也可以交互式调用,并且应该表现出相同的行为。

使用ps -ef ...和co变体来查找具有ppid的所有进程看起来可能非常难以移植。用$!不能在更深层次上工作,孩子们没有背景过程。

我尝试使用以下代码:

__cdist_kill_on_interrupt()
{
   __cdist_tmp_removal
   kill 0
   exit 1
}

trap __cdist_kill_on_interrupt INT TERM

但这会导致丑陋的终止消息以及shell中的段错误(破折号,bash,zsh),并且似乎不会立即停止所有内容:

# cdist-mass-deploy -p ikq04.ethz.ch ikq05.ethz.ch
core: Waiting for cdist-deploy-to jobs to finish
^CTerminated
Terminated
Terminated
Terminated
Segmentation fault

所以问题是,如何以可移植的方式干净地退出包括所有(子)子节点(bourne shell,不需要csh支持)?

1 个答案:

答案 0 :(得分:1)

您不需要处理^ C,这将导致信号被发送到整个进程组,这将终止所有不在后台的进程。所以你不需要捕获INT。

你杀死它们时获得终止的唯一原因是kill默认发送TERM,但如果你首先处理一个TERM,这是合理的。如果你想避免这些消息,你可以使用kill -INT 0。

(以额外信息回复)

如果子进程在后台运行,您可以在启动后立即获取进程ID,使用$!特殊的shell变量。将这些聚集在一个变量中,并在需要终止时将其全部删除。