如何在 Python 中使用 subprocess.check_output() ?

我已经找到了关于 subprocess.check _ output ()的文档,但是我找不到带参数的文档,而且文档也不是很深入。我正在使用 Python3(但是正在尝试通过 Python3运行 Python2文件)

我正在尝试运行这个命令: 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'])

321373 次浏览

正确的答案(使用 Python 2.7和更高版本,因为 check_output() 就是那时候介绍的)是:

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

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

py2.py:

import sys
print sys.argv

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'是完全相同的ーー你取一个 str,然后调用 str把它转换成一个 str。这使得代码更难阅读,更长,甚至更慢,而没有增加任何好处。

More seriously, python py2.py can't be a single argument, unless you're actually trying to run a program named, say, /usr/bin/python\ py2.py. Which you're not; you're trying to run, say, /usr/bin/python with first argument py2.py. So, you need to make them separate elements in the list.

您的第二个版本修复了这个问题,但是您在 test.txt'之前错过了 '。这应该给你一个 SyntaxError,可能说 EOL while scanning string literal

与此同时,我不知道您是如何找到文档的,但是找不到任何带参数的例子:

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

它使用一个额外的参数 "Hello World!"调用 "echo"命令。

另外:

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

我很确定 -i没有一个位置参数,但是一个可选参数。否则,句子的后半部分就没有意义了。

加上@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 错误——这个错误通常不能在 filenotfound 异常中捕获,否则您最终会得到

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

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

Since Python 3.5, subprocess.run is 建议 instead of 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=True或 Python 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