2

Killing subprocess created with shell=True passed to subprocess.Popen's constructor under Linux kills only shell and not the process created by shell (see How to terminate a python subprocess launched with shell=True). However python -c "import subprocess; subprocess.Popen(['ping', '-t', 'google.com'], shell=True).terminate()" run under Windows Vista x64 SP3 and Python 2.7.3 64bit kills the ping process. Under Windows subprocess.Popen.terminate() calls TerminateProcess. However documentation of this function states

Terminates the specified process and all of its threads.

There is no mention about terminating whole process tree. What am I missing?

Community
  • 1
  • 1
Piotr Dobrogost
  • 41,292
  • 40
  • 236
  • 366

1 Answers1

2

I think this is only with the one-liner you give, and my observations suggest that the ping does not even get started. If you run as a script (Windows 7):

import subprocess

proc = subprocess.Popen(['ping', '-t', 'google.com'], shell=True)

raw_input("<RETURN> to terminate")
proc.terminate()

raw_input("<RETURN> to end")

Then the proc.terminate() only terminates the shell, it does not terminate the ping!

However, if you set shell=False then it behaves as expected - it terminates the ping. Same behaviour on Python 2.7 and 3.2.

Edit: I tried this code as a one-liner as well, and got the same results as the questioner. I hate sleep hacks, but this works:

python -c "import subprocess,time;proc = subprocess.Popen(['ping','-t', 'google.com'], shell=True);time.sleep(1);proc.terminate()"
cdarke
  • 42,728
  • 8
  • 80
  • 84
  • Nice work. I get the same results on Windows XP SP3. Any idea why `sleep()` changes behavior? – Piotr Dobrogost Oct 22 '12 at 11:50
  • I can only guess. I suspect that the terminate kills the shell before it gets chance to launch `ping`. I looked at the 2.7 source code (Python-2.7.2/PC/_subprocess.c, function sp_TerminateProcess) and it did nothing unusual, it just calls `TerminateProcess`, as the doc says. – cdarke Oct 22 '12 at 12:13