Reputation: 7309
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
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