python cannot kill process using process.terminate
Question: I have a python code as following:

    
    
    import threading
    import time
    import subprocess, os, sys, psutil, signal
    from signal import SIGKILL
    
    def processing():
        global p_2
        global subp_2
        .
        .
        .
        if condition1: #loop again
              threading.Timer(10,processing).start()
        if condition2:
              signal.signal(signal.SIGINT, signal_handler)
              #signal.signal(signal.SIGTERM, signal_handler)
              subp_2.terminate()   
              #os.kill(subp_2.pid, 0)
              #subp_2.kill()            
              print " Status p_2: ", p_2.status
    
    def signal_handler(signal, frame):
        print('Exiting')
        sys.exit(0)
    
    def function():
        global p_1
        global subp_1
        .
        .
        .
        if condition1: #loop again
              threading.Timer(5,function).start()
    
        if condition2:
    
              signal.signal(signal.SIGINT, signal_handler)
              #signal.signal(signal.SIGTERM, signal_handler)
              subp_1.terminate()   
              #os.kill(subp_1.pid, 0)
              #subp_1.kill()            
              print " Status p_1: ", p_1.status
              threading.Timer(10,processing).start()  
              subp_2 =  subprocess.Popen('./myScript2.sh %s %s' % (arg0, arg1), shell=True)
              p_2 = psutil.Process(subp_2.pid)
    
    if __name__ == '__main__':
              global p_1
              global subp_1 
              .
              .
              .
              subp_1 = subprocess.Popen(["/.../myScript1.sh"],  shell=True)
              p_1 = psutil.Process(subp_1.pid)
              threading.Timer(5,function).start()
    

I could not kill the processe subp_1 and subp_2. Whatever I tried:
.terminate(), .kill() or os.kill() I am still getting process status running.
Could anyone tell me please what am I missing ? Any hint is appreciated.


Answer: When you use `shell=True`, first a subprocess is spawned which runs the shell.
Then the shell spawns a subprocess which runs `myScript2.sh`. The subprocess
running the shell can be terminated without terminating the `myScript2.sh`
subprocess.

If you can avoid using `shell=True`, then that would be one way to avoid this
problem. If using user input to form the command, `shell=True` should
definitely be avoided, since it is a [security
risk](https://docs.python.org/2/library/subprocess.html#subprocess.call).

On Unix, by default, the subprocess spawned by `subprocess.Popen` is _not_ a
[session leader](http://unix.stackexchange.com/q/18166/3330). When you send a
signal to a session leader, it is propagated to all processes with the same
session id. So to have the shell pass the `SIGTERM` to `myScript2.sh`, make
the shell a session leader.

For Python versions < 3.2 on Unix, that can be done by having the shell
process run `os.setsid()`:

    
    
    import os
    subp_2 =  subprocess.Popen('./myScript2.sh %s %s' % (arg0, arg1), 
                               shell=True, 
                               preexec_fn=os.setsid)
    
    # To send SIGTERM to the process group:
    os.killpg(subp_2.pid, signal.SIGTERM)
    

For Python versions >= 3.2 on Unix, pass `start_new_session=True` to `Popen`.

For Windows, see [J.F. Sebastian's
solution](http://stackoverflow.com/a/13256908/190597).

