我的脚本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支持)?
答案 0 :(得分:1)
您不需要处理^ C,这将导致信号被发送到整个进程组,这将终止所有不在后台的进程。所以你不需要捕获INT。
你杀死它们时获得终止的唯一原因是kill默认发送TERM,但如果你首先处理一个TERM,这是合理的。如果你想避免这些消息,你可以使用kill -INT 0。
(以额外信息回复)
如果子进程在后台运行,您可以在启动后立即获取进程ID,使用$!特殊的shell变量。将这些聚集在一个变量中,并在需要终止时将其全部删除。