6

我有一个大致如下所示的 Bash 脚本“脚本”:

#!/bin/bash

cmd1 | cmd2 | cmd3

当我做一个kill script(或更准确地说,当我在 中做一个“停止脚本”时supervisord),并不是所有的 cmd* 都被杀死了。我如何确保它们与生成它们的脚本一起被终止?

4

3 回答 3

6

Supervisord 有stopasgroupkillasgroup选项(默认为 false),它们决定是否将 SIGTERM/SIGKILL 信号传播到子进程。

[program:script]
command=script
stopasgroup=true
killasgroup=true

(这些配置变量都记录在http://supervisord.org/configuration.html。)

于 2012-02-23T12:11:41.087 回答
2

不确定如何使用supervisord,但pkill您可以使用-P从父进程到所有子进程终止的选项。这是进程树(从我正在运行的 ssh 守护程序开始)。

$ pstree -a -p 1792
sshd,1792
  ├─sshd,27150
  │   └─sshd,27153
  │       └─zsh,27154
  │           └─test.sh,27325 ./test.sh
  │               └─cat,27326
  └─sshd,27182
      └─sshd,27184
          └─zsh,27185
              └─pstree,27357 -a -p 1792

在一个会话中,我有一个test.shpid 为 27325 的脚本,而在另一个会话中,我正在运行该命令pstree -a -p 1792(因为sshd有 pid 1792)

在我运行之后pkill -TERM -P 27325

$ pstree -a -p 1792   
sshd,1792
  ├─sshd,27150
  │   └─sshd,27153
  │       └─zsh,27154
  └─sshd,27182
      └─sshd,27184
           └─zsh,27185
              └─pstree,27387 -a -p 1792

这个答案基本上是从stackoverflow上的另一个答案改写的:https ://stackoverflow.com/a/392155/263969

于 2012-02-23T00:18:46.557 回答
0

另一种解决方案是捕获 SIGTERM 并杀死陷阱代码中的所有孩子。

唯一的问题是,shell 仅在当前运行的命令完成后才为接收到的信号运行陷阱代码——所以在你的情况下,仅此一项是没有帮助的。

但是,如果 shell 处于“等待”状态,陷阱将以“异步”方式运行。

#!/usr/bin/env bash
trap 'kill 0' TERM
( cmd1 | cmd2 | cmd3 ) & wait

kill 0向当前进程组中的所有进程发送 SIGTERM 。

注意:我在这里谈论 Bash。

于 2012-12-21T18:11:19.387 回答