Bash管和SIGTERM

时间:2012-02-22 22:44:36

标签: linux bash pipe supervisord

我有一个Bash脚本“脚本”,大致如下:

#!/bin/bash

cmd1 | cmd2 | cmd3

当我执行kill script时(或更确切地说,当我在supervisord中执行“停止脚本”时),并非所有cmd *都被杀死。如何确保它们与产生它们的脚本一起终止?

3 个答案:

答案 0 :(得分:6)

Supervisord有 stopasgroup killasgroup 选项(默认为false),用于确定是否将SIGTERM / SIGKILL信号传播到子进程。

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

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

答案 1 :(得分: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

在一个会话中,我有一个带有pid 27325的脚本test.sh,而另一个会话我正在运行命令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

答案 2 :(得分:0)

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

唯一的问题是,只有在当前运行的命令完成后,shell才会为接收到的信号运行陷阱代码 - 所以在你的情况下,仅此一点就无济于事。

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

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

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

注意:我在这里谈论Bash。