你如何在 Python 中使用 subprocess.check_output()?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14078117/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do you use subprocess.check_output() in Python?
提问by JOHANNES_NY?TT
I have found documentation about subprocess.check_output() but I cannot find one with arguments and the documentation is not very in depth. I am using Python 3 (but am trying to run a Python 2 file through Python 3)
我找到了关于 subprocess.check_output() 的文档,但我找不到带参数的文档,而且文档不是很深入。我正在使用 Python 3(但我正在尝试通过 Python 3 运行 Python 2 文件)
I am trying to run this command:
python py2.py -i test.txt
我正在尝试运行此命令:
python py2.py -i test.txt
-i is a positional argument for argparse, test.txt is what the -i is, py2.py is the file to run
-i 是 argparse 的位置参数,test.txt 是 -i 是什么,py2.py 是要运行的文件
I have tried a lot of (non working) variations including:
py2output = subprocess.check_output([str('python py2.py '),'-i', 'test.txt'])
我尝试了很多(非工作)变体,包括:
py2output = subprocess.check_output([str('python py2.py '),'-i', 'test.txt'])
py2output = subprocess.check_output([str('python'),'py2.py','-i', test.txt'])
py2output = subprocess.check_output([str('python'),'py2.py','-i', test.txt'])
采纳答案by abarnert
The right answer (using Python 2.7 and later, since check_output()was introduced then) is:
正确答案(使用 Python 2.7 及更高版本,因为check_output()当时已引入)是:
py2output = subprocess.check_output(['python','py2.py','-i', 'test.txt'])
To demonstrate, here are my two programs:
为了演示,这里是我的两个程序:
py2.py:
py2.py:
import sys
print sys.argv
py3.py:
py3.py:
import subprocess
py2output = subprocess.check_output(['python', 'py2.py', '-i', 'test.txt'])
print('py2 said:', py2output)
Running it:
运行它:
$ python3 py3.py
py2 said: b"['py2.py', '-i', 'test.txt']\n"
Here's what's wrong with each of your versions:
以下是您的每个版本的问题所在:
py2output = subprocess.check_output([str('python py2.py '),'-i', 'test.txt'])
First, str('python py2.py')is exactly the same thing as 'python py2.py'—you're taking a str, and calling strto convert it to an str. This makes the code harder to read, longer, and even slower, without adding any benefit.
首先,str('python py2.py')与 - 您'python py2.py'正在使用str,并调用str将其转换为str. 这使得代码更难阅读、更长,甚至更慢,而且不会增加任何好处。
More seriously, python py2.pycan'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/pythonwith first argument py2.py. So, you need to make them separate elements in the list.
更严重的是,python py2.py不能是单个参数,除非您实际上是在尝试运行名为/usr/bin/python\ py2.py. 你不是;例如,您正在尝试/usr/bin/python使用第一个参数运行py2.py。所以,你需要让它们在列表中分开元素。
Your second version fixes that, but you're missing the 'before test.txt'. This should give you a SyntaxError, probably saying EOL while scanning string literal.
你的第二个版本修复了这个问题,但你错过了'之前的test.txt'. 这应该给你一个SyntaxError,大概是说EOL while scanning string literal。
Meanwhile, I'm not sure how you found documentation but couldn't find any examples with arguments. The very first example is:
同时,我不确定您是如何找到文档的,但找不到任何带有参数的示例。第一个例子是:
>>> subprocess.check_output(["echo", "Hello World!"])
b'Hello World!\n'
That calls the "echo"command with an additional argument, "Hello World!".
这会调用"echo"带有附加参数的命令,"Hello World!".
Also:
还:
-i is a positional argument for argparse, test.txt is what the -i is
-i 是 argparse 的位置参数,test.txt 是 -i 是什么
I'm pretty sure -iis nota positional argument, but an optional argument. Otherwise, the second half of the sentence makes no sense.
我敢肯定-i是不是一个位置参数,但一个可选的参数。否则,后半句没有任何意义。
回答by ravi.zombie
Adding on to the one mentioned by @abarnert
添加到@abernert 提到的那个
a better one is to catch the exception
更好的方法是捕获异常
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"
this stderr= subprocess.STDOUTis for making sure you dont get the filenotfound error in stderr- which cant be usually caught in filenotfoundexception, else you would end up getting
这个stderr=subprocess.STDOUT 是为了确保你不会在 stderr 中得到 filenotfound 错误——这通常不能在 filenotfoundexception 中捕获,否则你最终会得到
python: can't open file 'py2.py': [Errno 2] No such file or directory
Infact a better solution to this might be to check, whether the file/scripts exist and then to run the file/script
事实上,一个更好的解决方案可能是检查文件/脚本是否存在,然后运行文件/脚本
回答by Gohu
Since Python 3.5, subprocess.run()is recommended over subprocess.check_output():
从 Python 3.5 开始,推荐subprocess.run()而不是subprocess.check_output():
>>> subprocess.run(['cat','/tmp/text.txt'], stdout=subprocess.PIPE).stdout
b'First line\nSecond line\n'
Since Python 3.7, instead of the above, you can use capture_output=trueparameter to capture stdout and stderr:
从 Python 3.7 开始,您可以使用capture_output=true参数来捕获 stdout 和 stderr ,而不是上面的:
>>> subprocess.run(['cat','/tmp/text.txt'], capture_output=True).stdout
b'First line\nSecond line\n'
Also, you may want to use universal_newlines=Trueor its equivalent since Python 3.7 text=Trueto work with text instead of binary:
此外,您可能希望使用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
See subprocess.run()documentation for more information.
有关更多信息,请参阅subprocess.run()文档。

