David Michael Gang
David Michael Gang

Reputation: 7309

python subprocess - why causes a space in the arguments an error

This does work nice:

import subprocess
subprocess.check_call(["ls","-l"])

But this line causes an error:

>>> subprocess.check_call(["ls"," -l"])
ls: cannot access  -l: No such file or directory
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib64/python3.4/subprocess.py", line 558, in check_call
    raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['ls', ' -l']' returned non-zero exit status 2

Why does this happen?

In unix I can write:

ls                                           -l

with many spaces between ls and -l

I use Python 3.4.5 on Centos 6

Upvotes: 0

Views: 320

Answers (1)

Martijn Pieters
Martijn Pieters

Reputation: 1125078

In unix I can write:

You don't write that in unix. You write that in a shell. The shell parses that output and produces a list, after collapsing the whitespace. It then passes the equivalent of ['ls', '-l'] (no spaces!) to the ls process.

Different shells can treat whitespace differently. Most let you escape whitespace by using quotes or backslashes. So the following fails just as much in a shell as it does in Python:

$ ls ' -l'
ls:  -l: No such file or directory

With subprocess, unless you set shell=True, you are not passing the arguments through the shell, you pass this straight to the ls process that is started. So you have to deliver those arguments the way ls expects them to be delivered, with no spaces before the - for options.

If you need to split out commands and arguments in roughly the same way the shell does, use the shlex module:

>>> import shlex
>>> shlex.split("ls          -l")
['ls', '-l']
>>> shlex.split("ls ' -l'")
['ls', ' -l']

Upvotes: 3

Related Questions