96

我找到了关于 subprocess.check_output() 的文档,但是我找不到带参数的文档,而且文档不是很深入。我正在使用 Python 3(但正在尝试通过 Python 3 运行 Python 2 文件)

我正在尝试运行此命令: python py2.py -i test.txt

-i 是 argparse 的位置参数,test.txt 是 -i 是什么,py2.py 是要运行的文件

我尝试了很多(非工作)变体,包括: py2output = subprocess.check_output([str('python py2.py '),'-i', 'test.txt'])

py2output = subprocess.check_output([str('python'),'py2.py','-i', test.txt'])

4

3 回答 3

95

正确的答案(使用 Python 2.7 及更高版本,因为check_output() 是 then 引入的)是:

py2output = subprocess.check_output(['python','py2.py','-i', 'test.txt'])

为了演示,这是我的两个程序:

py2.py:

import sys
print sys.argv

py3.py:

import subprocess
py2output = subprocess.check_output(['python', 'py2.py', '-i', 'test.txt'])
print('py2 said:', py2output)

运行它:

$ python3 py3.py
py2 said: b"['py2.py', '-i', 'test.txt']\n"

以下是您的每个版本的问题:

py2output = subprocess.check_output([str('python py2.py '),'-i', 'test.txt'])

首先,str('python py2.py')与您'python py2.py'正在接受 astr并调用str将其转换为str. 这使得代码更难阅读,更长,甚至更慢,而没有增加任何好处。

更严重的是,python py2.py不能是单个参数,除非您实际上是在尝试运行一个名为/usr/bin/python\ py2.py. 你不是;例如,您正在尝试/usr/bin/python使用第一个参数运行py2.py。因此,您需要使它们在列表中成为单独的元素。

您的第二个版本解决了这个问题,但是您缺少'之前的test.txt'. 这应该给你一个SyntaxError,大概的说法EOL while scanning string literal

同时,我不确定您是如何找到文档的,但找不到任何带有参数的示例。第一个例子是:

>>> subprocess.check_output(["echo", "Hello World!"])
b'Hello World!\n'

这会调用"echo"带有附加参数的命令,"Hello World!".

还:

-i 是 argparse 的位置参数,test.txt 就是 -i

我很确定不是-i位置参数,而是可选参数。否则,句子的后半部分毫无意义。

于 2012-12-29T02:45:57.200 回答
31

从 Python 3.5 开始, 建议使用subprocess.run,而不是:subprocess.check_output

>>> subprocess.run(['cat','/tmp/text.txt'], check=True, stdout=subprocess.PIPE).stdout
b'First line\nSecond line\n'

从 Python 3.7开始,您可以使用capture_output=true参数来捕获 stdout 和 stderr,而不是上面的:

>>> subprocess.run(['cat','/tmp/text.txt'], check=True, capture_output=True).stdout
b'First line\nSecond line\n'

此外,您可能希望使用universal_newlines=TruePython 3.7 之后的等价物text=True来处理文本而不是二进制文件:

>>> stdout = subprocess.run(['cat', '/tmp/text.txt'], check=True, capture_output=True, text=True).stdout
>>> print(stdout)
First line
Second line
于 2019-04-19T08:23:59.257 回答
13

添加到@abarnert 提到的那个

更好的方法是捕获异常

import subprocess
try:
    py2output = subprocess.check_output(['python', 'py2.py', '-i', 'test.txt'],stderr= subprocess.STDOUT)  
    #print('py2 said:', py2output)
    print "here"
except subprocess.CalledProcessError as e:
    print "Calledprocerr"

这个stderr= subprocess.STDOUT 是为了确保你不会在 stderr 中得到 filenotfound 错误-通常不能在 filenotfoundexception 中捕获,否则你最终会得到

python: can't open file 'py2.py': [Errno 2] No such file or directory

事实上,更好的解决方案可能是检查文件/脚本是否存在,然后运行文件/脚本

于 2015-10-30T06:17:14.043 回答