1 回答
TA贡献1946条经验 获得超4个赞
双方check_call并check_output应传递命令的列表由指挥系统(即会被发送到相同的命令列表中运行Popen)。这两个都是阻塞调用,这意味着 Python 将等到它们完成运行更多代码。
UsingPopen将命令列表发送到命令系统,但不会阻止 Python 代码的进一步执行。您可以使用对象的.poll方法检查进程Popen,或者您可以进行阻塞调用,使用.communicate它将返回标准输出和标准错误流的元组。
假设你想要执行命令的结果,并且命令会正确地向错误流报告错误,你可以使用:
process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = process.communicate()
if err:
print('The process raised an error:', err.decode())
这里有些例子:
使用Popen:
import subprocess
# first a command that works correctly
proc = subprocess.Popen(['ls', '-a'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = proc.communicate()
if not err:
print('--No errors--\n', out.decode())
else:
print('--Error--\n', err.decode())
# prints:
--No errors--
anaconda3
Desktop
Documents
Downloads
# next a command, which generates an error. The `-w` switch is invalid
proc = subprocess.Popen(['ls', '-w'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = proc.communicate()
if not err:
print('--No errors--\n', out.decode())
else:
print('--Error--\n', err.decode())
# prints:
--Error--
ls: option requires an argument -- 'w'
Try 'ls --help' for more information.
使用 check_call
check_call 如果来自命令系统的返回码不是 0,则会引发 Python 异常。
# first with a working command:
ret_code = subprocess.check_call(['ls', '-a'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
ret_code
# returns:
0
# and now with the command that generates an error:
ret_code = subprocess.check_call(['ls', '-w'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# raises an exception:
---------------------------------------------------------------------------
CalledProcessError Traceback (most recent call last)
<ipython-input-25-3cd5107991a2> in <module>()
----> 1 ret_code = subprocess.check_call(['ls', '-w'], stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
~/anaconda3/lib/python3.6/subprocess.py in check_call(*popenargs, **kwargs)
289 if cmd is None:
290 cmd = popenargs[0]
--> 291 raise CalledProcessError(retcode, cmd)
292 return 0
293
CalledProcessError: Command '['ls', '-w']' returned non-zero exit status 2.
要处理异常,请使用try/except块。
try:
ret_code = subprocess.check_call(['ls', '-w'], stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
except subprocess.CalledProcessError as e:
ret_code = e.returncode
print('An error occurred. Error code:', ret_code)
# prints:
An error occurred. Error code: 2
使用 check_output
check_output非常相似,check_call如果来自命令系统的返回码不是 0,它将引发 Python 异常。但是,如果返回码为 0,它将返回标准输出流中的输出。
# just with the error process this time
try:
ret_code = subprocess.check_output(['ls', '-w'], stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
except subprocess.CalledProcessError as e:
ret_code = e.returncode
print('An error occurred. Error code:', ret_code)
# prints:
An error occurred. Error code: 2
添加回答
举报