Killing a sub-subprocess from python/bash without leaving orphans
<p>I have a system with 3 main components (everything running on Ubuntu14.04 and Python 2.7, don't care too much about portability):</p>

<p>a) Some binary that executes, let's call it <code>runtime</code>, it writes some values to <code>stdout</code> and <code>stderr</code> that I need to read from (c)</p>

<p>b) A launcher script that set's up the environment and executes <code>runtime</code>, let's call it <code>launcher</code>, it looks something like this:</p>

<pre><code>#!/bin/bash

#Needed by the runtime
export SOME_VAR=1234 
source some_file.sh
#...
exec runtime --option1 $1 --option2 $2
</code></pre>

<p>c) A server, it handles remote requests and calls the <code>launcher</code> when a remote client requests it. The server is written in python and needs to read the <code>stdX</code> from (a). I'm calling <code>launcher</code> using the subprocess module:</p>

<pre><code># When calling the launcher script:
cmd = "launcher value1 value2"
p = subprocess.Popen(cmd, 
    stdout=subprocess.PIPE, 
    stderr=subprocess.STDOUT,
    shell=True)
# read p.stdout ...
</code></pre>

<p>This creates 2 new processes, 1 for the <code>launcher</code> script (e.g. pid:10000) and other for the <code>runtime</code> (e.g. pid:10001), running <code>htop</code> with <code>tree</code> shows something similar to this:</p>

<pre><code>PID    ...  Command
12345  ...  python server.py
10000  ...    |- /bin/sh -c ./launcher value1 value2
10001  ...        |- runtime --option1 value1 --option2 value2
</code></pre>

<p>At some point, the <code>server</code> want's to stop the <code>runtime</code> process (by sending a <code>SIGTERM</code>)</p>

<pre><code># When trying to stop the runtime:
os.kill(p.pid, signal.SIGTERM)
# Have also tried with p.terminate(), same results.
</code></pre>

<p>The problem is that this only kills the <code>launcher</code> process (pid:10000), leaving the <code>runtime</code> executing indefinitely. I want to properly propagate the <code>SIGTERM</code> to the <code>runtime</code> whenever the <code>server</code> requests it (<code>runtime</code> MUST receive this signal to stop and exit gracefully, otherwise it will produce data corruption).</p>

<p>I've tried using <code>os.killpg(...)</code> to kill the whole process group, but it also kills the <code>server</code> (obviously).</p>

<p><strong>How can I properly propagate a SIGTERM signal to a sub-sub-process?</strong></p>

<p>Use process group this way:</p>

<pre><code>p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
                    shell=True, preexec_fn=os.setpgrp)

os.killpg(os.getpgid(p.pid), signal.SIGTERM)
</code></pre>

python linux bash ubuntu subprocess