[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