Ahm*_*d A 60 python python-3.x
我阅读了subprocess提供的函数 - call,check_call,check_output,并了解每个函数的工作方式和功能之间的差异.我目前正在使用check_output,所以我可以访问stdout,并使用"try block"来捕获异常,如下所示:
# "cmnd" is a string that contains the command along with it's arguments.
try:
cmnd_output = check_output(cmnd, stderr=STDOUT, shell=True, timeout=3, universal_newlines=True);
except CalledProcessError:
print("Status : FAIL")
print("Output: \n{}\n".format(cmnd_output))
Run Code Online (Sandbox Code Playgroud)
我遇到的问题是抛出异常时,"cmnd_output"未初始化并且无法访问stderr,我收到以下错误消息:
print("Output: \n{}\n".format(cmnd_output))
UnboundLocalError: local variable 'cmnd_output' referenced before assignment
Run Code Online (Sandbox Code Playgroud)
我认为那是因为异常导致"check_output"立即保释而没有任何进一步的处理,也就是在try块中分配给"cmnd_output".如果我错了,请纠正我.
有没有什么方法可以访问stderr(如果它被发送到stout就没关系)并且可以访问退出代码.我可以根据退出代码手动检查通过/失败,但不会发生异常.
艾哈迈德,谢谢你.
war*_*iuc 88
试试这个版本:
import subprocess
try:
output = subprocess.check_output(
cmnd, stderr=subprocess.STDOUT, shell=True, timeout=3,
universal_newlines=True)
except subprocess.CalledProcessError as exc:
print("Status : FAIL", exc.returncode, exc.output)
else:
print("Output: \n{}\n".format(output))
Run Code Online (Sandbox Code Playgroud)
这样,只有在呼叫成功时才会打印输出.如果CalledProcessError您打印返回代码和输出.
oar*_*alo 53
接受的解决方案涵盖了你都OK混合的情况下stdout和stderr,但在案件中,子进程(无论何种原因)决定使用stderr除stdout用于非失败输出(即输出非严重警告),然后给定的解决方案可能不合适.
例如,如果您将对输出执行其他处理,例如转换为JSON,并且混合使用stderr,则整个过程将失败,因为输出将不是纯JSON,因为添加了stderr输出.
在这种情况下我发现以下内容:
cmd_args = ... what you want to execute ...
pipes = subprocess.Popen(cmnd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
std_out, std_err = pipes.communicate()
if pipes.returncode != 0:
# an error happened!
err_msg = "%s. Code: %s" % (std_err.strip(), pipes.returncode)
raise Exception(err_msg)
elif len(std_err):
# return code is 0 (no error), but we may want to
# do something with the info on std_err
# i.e. logger.warning(std_err)
# do whatever you want with std_out
# i.e. json.loads(std_out)
Run Code Online (Sandbox Code Playgroud)
两种建议的解决方案要么混合使用stdout / stderr,要么使用Popen不像那样简单的方法check_output。但是,check_output如果仅通过使用管道捕获stderr,则可以完成同一件事,并保持stdout / stderr分开:
import sys
import subprocess
try:
subprocess.check_output(cmnd, stderr=subprocess.PIPE)
except subprocess.CalledProcessError as e:
print('exit code: {}'.format(e.returncode))
print('stdout: {}'.format(e.output.decode(sys.getfilesystemencoding())))
print('stderr: {}'.format(e.stderr.decode(sys.getfilesystemencoding())))
Run Code Online (Sandbox Code Playgroud)
在此示例中,由于我们捕获了stderr,因此可在异常的stderr属性中使用它(如果不使用管道进行捕获,则为None)。
| 归档时间: |
|
| 查看次数: |
51042 次 |
| 最近记录: |