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

时间:2012-12-29 02:11:40

标签: python python-3.x python-2.x

我找到了有关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'])

3 个答案:

答案 0 :(得分:61)

正确答案(使用Python 2.7及更高版本,因为check_output() was introduced 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'完全相同 - 您正在使用str,并呼叫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 不是一个位置参数,而是一个可选参数。否则,句子的后半部分没有意义。

答案 1 :(得分:7)

添加@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错误 - 这通常不会被文件陷入文件错误,否则你最终会得到

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

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

答案 2 :(得分:0)

自Python 3.5起,推荐subprocess.run()胜过subprocess.check_output()

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

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

>>> subprocess.run(['cat','/tmp/text.txt'], 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'], capture_output=True, text=True).stdout
>>> print(stdout)
First line
Second line

有关更多信息,请参见subprocess.run()文档。