Fighting with subprocess.Popen

Nobody nobody at
Mon Feb 15 17:50:13 CET 2010

On Sun, 14 Feb 2010 21:43:22 +0100, Christian Heimes wrote:

>> Below is a test case that demonstrates this. Tests 1 & 2 concatenate the
>> command and the argument, Tests 3 & 4 mimic the python docs and use the form
>> Popen(["mycmd", "myarg"], ...), which never seems to work.
> It doesn't work with shell=True because the shell is not able to
> interpret the list form. It's recommended that you don't use shell=True
> unless you need a shell.

A more general rule is to use shell=True on Windows and shell=False on
Unix (including MacOSX).

On Windows, whether the command is a list or a string is entirely
orthogonal to whether a shell is used. The underlying execution function
(CreateProcess) always uses a string, so a list is always converted to a
string, and the conversion is independent of the shell= setting.

The difference between shell=False and shell=True is that the former
passes the string directly to CreateProcess while the latter passes
"cmd.exe /c "+string (cmd.exe is actually the value of %comspec% if it
is set).

The reason for using shell=True on Windows is that it allows the program
to be a batch file (or other script), while shell=False only works if the
program is a binary executable (.exe, .com).

On Unix, passing the arguments as a list in conjunction with shell=True
rarely makes sense. It results in the execution of

	["/bin/sh", "-c"] + args

i.e. args[0] is the argument to "-c" while the remaining arguments are
assigned to the shell variables $1, $2, etc. If you're using the
shell, you usually you want to pass the entire command as a string,
resulting in the execution of

	["/bin/sh", "-c", command]

More information about the Python-list mailing list