6

I have a Bash script "script" which roughly looks like:

#!/bin/bash

cmd1 | cmd2 | cmd3

When I do a kill script (or more precisely when I do a 'stop script' in supervisord), not all cmd* are killed. How can I make sure they are terminated along with the script that spawned them?

Mark Amery
  • 143,130
  • 81
  • 406
  • 459
jldupont
  • 93,734
  • 56
  • 203
  • 318

3 Answers3

6

Supervisord has stopasgroup and killasgroup options (false by default) which determine whether to propagate SIGTERM/SIGKILL signals to child processes.

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

(These config variables are both documented at http://supervisord.org/configuration.html.)

Mark Amery
  • 143,130
  • 81
  • 406
  • 459
mher
  • 10,508
  • 2
  • 35
  • 27
2

Not sure about how using supervisord, but with pkill you can use the -P option to kill from a parent process down to all the children. Here's the process trees (starting from my running ssh daemon).

$ 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 one session I have a script test.sh with pid 27325, and in the other I'm running the command pstree -a -p 1792 (because sshd had pid 1792)

And after I run 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

This answer was essentially rephrased from the this other answer on stackoverflow: https://stackoverflow.com/a/392155/263969

Community
  • 1
  • 1
Tim Bielawa
  • 6,935
  • 2
  • 17
  • 11
0

Another solution is to trap SIGTERM and kill all children in the trap-code.

The only thing is that the shell runs trap-code for a received signal only after the currently running command has completed -- so in your case, this alone wouldn't help.

However, traps will be run in an "async" kind of way if the shell is in "wait".

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

The kill 0 sends SIGTERM to all processes in the current process group.

NOTE: I'm talking about Bash here.

schieferstapel
  • 1,025
  • 10
  • 15