[Tutor] subprocess.call list vs. str argument
eryksun
eryksun at gmail.com
Tue Feb 25 21:37:31 CET 2014
On Tue, Feb 25, 2014 at 2:52 PM, Albert-Jan Roskam <fomcl at yahoo.com> wrote:
> Here is why I used "shell=True" before. Is it related to the
> file paths?
>
> cmd = (r'sphinx-apidoc '
> r'-f -F '
> r'-H "%(title)s" '
> r'-A "%(author)s" '
> r'-V "%(version)s" '
> r'-o %(output_dir)s %(input_dir)s') % locals()
> retcode = subprocess.call(cmd)
Take a look at the code in subprocess._execute_child for POSIX platforms:
if isinstance(args, types.StringTypes):
args = [args]
else:
args = list(args)
if shell:
args = ["/bin/sh", "-c"] + args
if executable:
args[0] = executable
if executable is None:
executable = args[0]
It calls os.execvp in the child process, for which you want the
executable file argument to be 'sphinx-apidoc'. But without
shell=True, you can see that Popen uses your entire cmd string as the
executable.
FYI, in Windows the situation is different. CreateProcess takes a
string argument, so the setup code changes to the following:
if not isinstance(args, types.StringTypes):
args = list2cmdline(args)
# Process startup details
if startupinfo is None:
startupinfo = STARTUPINFO()
if None not in (p2cread, c2pwrite, errwrite):
startupinfo.dwFlags |= _subprocess.STARTF_USESTDHANDLES
startupinfo.hStdInput = p2cread
startupinfo.hStdOutput = c2pwrite
startupinfo.hStdError = errwrite
if shell:
startupinfo.dwFlags |= _subprocess.STARTF_USESHOWWINDOW
startupinfo.wShowWindow = _subprocess.SW_HIDE
comspec = os.environ.get("COMSPEC", "cmd.exe")
args = '{} /c "{}"'.format (comspec, args)
It's fine to use a string for args in Windows, and you may need to if
the program parses the command line differently than list2cmdline,
which escapes the arguments according to the rules used by Microsoft's
CRT.
More information about the Tutor
mailing list