2012-02-22 5 views
5

Ho uno script bash "script", che grosso modo si presenta come:bash pipe & SIGTERM

#!/bin/bash 

cmd1 | cmd2 | cmd3 

Quando faccio un kill script (o più precisamente quando faccio un 'copione stop' in supervisord), non tutti cmd * vengono uccisi. Come posso assicurarmi che siano terminati insieme allo script che li ha generati?

+0

Forse dovrebbe essere su [su]? –

risposta

5

Supervisord dispone di un'opzione killasgroup (false per impostazione predefinita) che determina se propagare i segnali di arresto/terminazione ai processi figlio.

[program:script] 
command=script 
killasgroup=true 

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

+0

Sembra molto promettente anche se al momento non posso davvero testarlo: ho aggiunto un controllo basato su 'parent pid' a tutti i miei script in modo che i processi figlio escano da soli quando il processo padre cambia (in '1' molto probabilmente). – jldupont

+2

* (La modifica suggerita da Anonimo è stata spostata nel commento) * Probabilmente si vorrà anche impostare su true l'opzione stopasgroup per essere certi che questo comportamento venga utilizzato in ogni situazione (ad esempio con il comando "restart"). Si noti che queste opzioni non sono presenti nelle versioni precedenti di supervisore. – Andomar

2

Non sono sicuro di come utilizzare supervisord, ma con pkill è possibile utilizzare l'opzione -P per terminare da un processo padre a tutti i figli. Ecco gli alberi dei processi (a partire dal mio demone ssh in esecuzione).

$ 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 

In una sessione di Ho uno script test.sh con pid 27325, e l'altra che sto eseguendo il comando pstree -a -p 1792 (perché sshd avevano pid 1792)

E dopo corro 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 

la risposta è stata sostanzialmente riformulato dal quest'altra risposta su StackOverflow: https://stackoverflow.com/a/392155/263969

+0

+1 Interessante ma non esattamente quello di cui ho bisogno. – jldupont

0

Un'altra soluzione è quella di intrappolare SIGTERM e uccidere tutti i bambini della trappola-codice.

L'unica cosa è che la shell esegue trap-code per un segnale ricevuto solo dopo il completamento del comando attualmente in esecuzione - quindi nel tuo caso, questo da solo non sarebbe d'aiuto.

Tuttavia, i trap verranno eseguiti in modo "asincrono" se la shell è in "attesa".

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

Il kill 0 invia SIGTERM a tutti i processi nel gruppo processo corrente.

NOTA: Sto parlando di Bash qui.