$ ls -ls ~rbarakx
total 0
0 drwxr-xr-x 1 Administrator None 0 Aug 21 17:54 bash
0 drwxr-xr-x 1 Administrator None 0 Jul 11 09:11 python
Python:
>>> subprocess.call(["ls","-ls","~rbarakx"],shell=True)
RCS mecha.py print_unicode.py req.py requests_results.html selen.py
0
It looks as if subprocess.call is executing just ls.
Can you suggest why?
My Environment:
Python: Python 2.7.3 (default, Dec 18 2012, 13:50:09) [GCC 4.5.3] on cygwin
cygwin: CYGWIN_NT-6.1-WOW64 ... 1.7.22(0.268/5/3) ... i686 Cygwin
windows: Windows 7 Ultimate
Because on Unix (cygwin) your call is equivalent to:
# WRONG: DON'T DO IT
rc = subprocess.call(["/bin/sh", "-c"] + ["ls","-ls","~rbarakx"])
In other words the argument list is passed to the shell itself i.e., ls doesn't see -ls or ~rbarakx they are considerred /bin/sh arguments.
What you want is:
rc = subprocess.call(["/bin/sh", "-c"] + ["ls -ls ~rbarakx"])
Or using shell=True:
rc = subprocess.call("ls -ls ~rbarakx", shell=True)
Here's the quote from subprocess docs for reference:
On Unix with shell=True, the shell defaults to /bin/sh. If args is a string, the string specifies the command to execute through the shell. This means that the string must be formatted exactly as it would be when typed at the shell prompt. This includes, for example, quoting or backslash escaping filenames with spaces in them. If args is a sequence, the first item specifies the command string, and any additional items will be treated as additional arguments to the shell itself. That is to say, Popen does the equivalent of:
Popen(['/bin/sh', '-c', args[0], args[1], ...])
You could also execute the command without any shell:
import os
import subprocess
rc = subprocess.call(["ls", "-ls", os.path.expanduser("~rbarakx")])
subprocess.call(["ls -ls ~"], shell=True)
If you insist on using tuple, consider the following workaround:
cmd = subprocess.list2cmdline(["ls","-ls","~rbarakx"])
subprocess.call(cmd, shell=True)
or this:
from os.path import expanduser
subprocess.call(["ls","-ls", expanduser("~rbarakx")])