[Tutor] subprocess.call list vs. str argument

Oscar Benjamin oscar.j.benjamin at gmail.com
Wed Feb 26 15:38:43 CET 2014


On 26 February 2014 08:50, Albert-Jan Roskam <fomcl at yahoo.com> wrote:
>
> Yesterday evening (it was *late* so forgive me if I wrong) I realized that part of my confusion was also caused by the fact that I ran my code in Idle.
> If I called subprocess.call with a list argument, it  returned code 0 (success) but the generated sphinx code was not the same as when I ran the program from the terminal. I concluded that this is some weird interaction between Idle (which may also run in a subprocess??) and my own program. I also had no problems when I ran (in the terminal): python -c "import subprocess; subprocess.call(['sphinx-apidoc'...(etc)])"
>
> I was surprised that the list elements of the argument for subprocess.call *have to be* separate tokens, e.g. (earlier in one of Danny's replies): a token (list element) '-f -F' won't work, it has to be two separate elements/tokens: '-f', '-F'. Apparently, subprocess.call is more than just a convenience function that " ".joins the list and escapes the resulting string.

At the operating system level there is no "command line" as such on
posix (Linux, Mac etc.). The command to run a program is a string
giving the name of the program and you can also pass a list of strings
to the program as "arguments". The command line is something that
happens in the shell (e.g. bash). Whereas Python would use quotes and
commas to separate strings in a list of strings the shell just assumes
that whitespace separates strings.

So in Python you would write
    ['qwe', 'asd', 'zxc zxc']
and it's clear that you have a list of three strings. In the shell
(e.g. bash) you would type
    qwe asd "zxc zxc"
and the shell understands that as three separate strings. The quotes
are needed to distinguish it from 4 strings because shell syntax
assumes that spaces separate strings.

So the idea of the "command line" as a single string that must be
split on whitespace is just something that happens in the shell. It is
supposed to be a convenient way of typing commands in the interactive
shell i.e. it would slow me down if I has to put in square brackets
quotes and commas every time I wanted to type a command in the shell
like ['ls', '-l', '~/mystuff']. But this convenience comes at a price
in that it becomes hard to handle strings that have spaces in them.
I've never really figured out how to write a non-trivial shell script
that can properly handle whitespace (it's easier to just avoid putting
spaces in filenames - or write the script in Python).

So really I think it's a good thing that Python lets you clearly
delineate each string in the argument list:
    subprocess.call(['ls', '-l', foldername])
without needing to worry about whether or not foldername contains spaces.


Oscar


More information about the Tutor mailing list