5

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 ?

Anjaneyulu
  • 434
  • 5
  • 21
  • Do you need to do this with ``subprocess.call`` or are other ``subprocess`` functions fine for launching your process? What is your condition for killing the process - time, output, ...? – MisterMiyagi Apr 02 '20 at 16:39
  • Yes It has to be blocking process and the killing condition would be with key board interrupts like Ctrl+C and also sometimes with output – Anjaneyulu Apr 02 '20 at 16:44
  • Possible duplicate of https://stackoverflow.com/questions/38360420/how-to-kill-a-subprocess-called-using-subprocess-call-in-python –  Apr 12 '20 at 17:16
  • Possible duplicate of [How to terminate a python subprocess launched with shell=True](https://stackoverflow.com/q/4789837/7509065) – Joseph Sible-Reinstate Monica Apr 12 '20 at 17:22

3 Answers3

9

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)
bmcculley
  • 2,048
  • 1
  • 14
  • 17
4

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.

Roland Smith
  • 42,427
  • 3
  • 64
  • 94
2

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.

sytech
  • 29,298
  • 3
  • 45
  • 86