2012-02-22 81 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。