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

lzfw57am  于 2023-03-31  发布在  Python
关注(0)|答案(4)|浏览(205)

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

5jdjgkvh

5jdjgkvh1#

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

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的程序。比如说,你想运行第一个参数为py2.py/usr/bin/python,所以,你需要把它们作为列表中的独立元素。
您的第二个版本修复了这个问题,但是在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 * 不是 * 一个位置参数,而是一个可选参数。否则,句子的后半部分没有意义。

6pp0gazn

6pp0gazn2#

**从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=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
sd2nnvve

sd2nnvve3#

添加到@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中得到filenotfounderror-filenotfoundException中通常不能捕捉到这个错误,否则你最终会得到

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

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

fkvaft9z

fkvaft9z4#

@ravi.zombie的答案适用于python 3,即使存在非零退出代码错误也会产生输出:

try:
    out = subprocess.check_output(['git','commit','-m', commit_message], stderr= subprocess.STDOUT ).decode()
except subprocess.CalledProcessError as e:
    print ('[ERROR]: Exit code != 0')
    out = e.output.decode()
print(out)

相关问题