2012-02-22 42 views
5

我有一个bash脚本,“脚本”,这大致是这样的:bash的管道与SIGTERM

#!/bin/bash 

cmd1 | cmd2 | cmd3 

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

+0

也许应该在[su]上? – 2012-02-23 00:07:30

回答

5

Supervisord有一个killasgroup选项(默认为false),它决定是否将停止/终止信号传播给子进程。

[program:script] 
command=script 
killasgroup=true 

https://github.com/Supervisor/supervisor/blob/master/supervisor/process.py#L354

+0

看起来非常有希望,尽管目前我还不能真正测试它:我已经为所有脚本添加了“基于父pid”的检查,以便在父进程更改时自动退出子进程(最可能为'1' )。 – jldupont 2012-02-23 13:56:21

+2

*(来自Anonymous的建议编辑已移至注释中)*您可能还希望将stopasgroup选项设置为true以确保在每种情况下都使用此行为(例如,使用“restart”命令)。请注意,这些选项在老版本的主管中不存在。 – Andomar 2012-06-19 21:30:46

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.sh具有PID 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 

这个答案本质上是从这个其他答案改写:https://stackoverflow.com/a/392155/263969

+0

+1有趣但不完全是我所需要的。 – jldupont 2012-02-23 13:54:58

0

另一个解决方案是陷阱SIGTERM和杀死陷阱代码的所有儿童。

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

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

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

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

注:我在这里讨论Bash。