Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do we kill the process spawned by subprocess.call() function in python?

I have created a process with subprocess.call in python

import subprocess
x = subprocess.call(myProcess,shell=True)

I want to kill both the processes i.e the shell and its child process(my process).

With subprocess.call() I only get the return code of the process

Can anyone help with this ?

like image 730
Anjaneyulu Avatar asked Apr 02 '20 16:04

Anjaneyulu


3 Answers

You'll have to move away from subprocess.call to do it but it will still achieve the same results. Subprocess call runs the command passed, waits until completion then returns the returncode attribute. In my example I show how to get the returncode upon completion if needed.

Here's an example of how to kill a subprocess, you'll have to intercept the SIGINT (Ctrl+c) signal in order to terminate the subprocess before exiting the main process. It's also possible to get the standard output, standard error, and returncode attribute from the subprocess if needed.

#!/usr/bin/env python
import signal
import sys
import subprocess

def signal_handler(sig, frame):
    p.terminate()
    p.wait()
    sys.exit(0)

signal.signal(signal.SIGINT, signal_handler)

p = subprocess.Popen('./stdout_stderr', shell=True, 
    stderr=subprocess.PIPE, stdout=subprocess.PIPE)
# capture stdout and stderr
out, err = p.communicate()
# print the stdout, stderr, and subprocess return code
print(out)
print(err)
print(p.returncode)
like image 141
bmcculley Avatar answered Oct 22 '22 22:10

bmcculley


You can't when using subprocess.call, because it interrupts your program while running the subprocess.

How to kill a subprocess created with subprocess.Popen is answered in this question.

like image 45
Roland Smith Avatar answered Oct 22 '22 23:10

Roland Smith


You want to use Popen. Here's what subprocess.call looks like:

def call(*popenargs, timeout=None, **kwargs):
"""Run command with arguments.  Wait for command to complete or
timeout, then return the returncode attribute.

The arguments are the same as for the Popen constructor.  Example:

retcode = call(["ls", "-l"])
"""
with Popen(*popenargs, **kwargs) as p:
    try:
        return p.wait(timeout=timeout)
    except:  # Including KeyboardInterrupt, wait handled that.
        p.kill()
        # We don't call p.wait() again as p.__exit__ does that for us.
        raise

subprocess.call is made specifically to wait for the process to finish before returning. So, by the time subprocess.call finishes, there's nothing to be killed.

If you want to start a subprocess then do other things while it's running, including killing the process, you should use subprocess.Popen directly instead.

like image 35
sytech Avatar answered Oct 22 '22 22:10

sytech