Issue 26534: subprocess.check_output with shell=True ignores the timeout (original) (raw)

Basically - subprocess.check_output("ping localhost", shell=True, timeout=5) Will hang forever.

What happens is that subprocess.run times out on communicate, sends SIGKILL to the shell and then calls communicate again without the timeout. But nothing actually closes the "ping" command so the second communicate will never exit.

Even if we put a timeout on the second communicate, it won't be good enough because that "ping" will still be "leaked".

This SO question is about the fact that kill doesn't work when shell=True, and might be relevant for this issue: http://stackoverflow.com/questions/4789837/how-to-terminate-a-python-subprocess-launched-with-shell-true

As a possible fix I propose doing the following:

  1. Add killpg to the Popen class.
  2. Add an argument to run - "kill_group" that makes run use killpg instead of kill
  3. Users can all: subprocess.check_output("ping localhost", shell=True, start_new_session=True, kill_group=True, timeout=5)

And have it work fine. This is the best I could come up with, without breaking any existing behavior.

Other options to consider:

  1. Not have kill_group argument and to implicitly kill by group when start_new_session is True (but this is not really backwards compatible).
  2. Having kill_group as an argument for Popen and not run, and when kill is called, it will call killpg if the option was specified.

A patch is attached with my proposed solution.

I don’t know enough about process groups and sessions to properly review, but some things that stand out: