第17.1.1.1节。 documentation个州:
如果shell为True,则将通过shell执行指定的命令。如果您主要使用Python来提供它在大多数系统shell上提供的增强控制流,并且仍然希望方便地访问其他shell功能,例如shell管道,文件名通配符,环境变量扩展以及将〜扩展到用户家中,这将非常有用。 。目录
但是,在 cygwin 上, bash 的输出与 Python的子进程的输出不同,即:
击:
$ 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
看起来 subprocess.call 正在执行 ls 。
你能说明原因吗?
我的环境:
Python :Python 2.7.3(默认,2012年12月18日,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旗舰版
答案 0 :(得分:4)
在Windows上,shell(cmd.exe
)不支持将~
扩展到用户的主目录。就此而言,也不是通配符扩展。在这一点上,Python文档非常面向UNIX / Linux。
“但是等等!”我听到你哭了。 “我安装了cygwin
,我有bash
!”当然有,但你几乎不能指望Python知道这一点。你在Windows上,所以它将使用Windows shell。如果没有,那么期望shell为cmd.exe
的Python脚本将会非常困惑。
答案 1 :(得分:3)
有趣的是,当将命令作为字符串而不是元组传递时,它似乎就像在bash中执行它一样。
subprocess.call(["ls -ls ~"], shell=True)
如果您坚持使用元组,请考虑以下解决方法:
cmd = subprocess.list2cmdline(["ls","-ls","~rbarakx"])
subprocess.call(cmd, shell=True)
或者这个:
from os.path import expanduser
subprocess.call(["ls","-ls", expanduser("~rbarakx")])
答案 2 :(得分:3)
看起来subprocess.call正在执行ls。
你能说明原因吗?
因为在Unix(cygwin)上你的电话相当于:
# WRONG: DON'T DO IT
rc = subprocess.call(["/bin/sh", "-c"] + ["ls","-ls","~rbarakx"])
换句话说,参数列表会传递给shell本身,即ls
看不到-ls
或~rbarakx
它们被认为是/bin/sh
个参数。
你想要的是:
rc = subprocess.call(["/bin/sh", "-c"] + ["ls -ls ~rbarakx"])
或使用shell=True
:
rc = subprocess.call("ls -ls ~rbarakx", shell=True)
以下是subprocess
docs for reference的引用:
在Unix上
shell=True
,shell默认为/bin/sh
。如果args
是 string,string指定通过shell执行的命令。 这意味着字符串必须完全按照原样进行格式化 在shell提示符下键入时。这包括,例如,引用或 反斜杠转义文件名,其中包含空格。 如果args是 sequence,第一项指定命令字符串,以及任何 其他项目将被视为shell的附加参数 也就是说,Popen相当于:Popen(['/bin/sh', '-c', args[0], args[1], ...])
强调是我的
您也可以在没有任何shell的情况下执行命令:
import os
import subprocess
rc = subprocess.call(["ls", "-ls", os.path.expanduser("~rbarakx")])