python – 如何使子进程只传达错误
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了python – 如何使子进程只传达错误,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3549字,纯文字阅读大概需要6分钟。
内容图文
![python – 如何使子进程只传达错误](/upload/InfoBanner/zyjiaocheng/964/e42aa108a06646bfaa55e4f7bfd34a7b.jpg)
我们已经在许多项目中创建了一个商品函数,它使用子进程来启动命令.这个功能如下:
def _popen( command_list ):
p = subprocess.Popen( command_list, stdout=subprocess.PIPE,
stderr=subprocess.PIPE )
out, error_msg = p.communicate()
# Some processes (e.g. system_start) print a number of dots in stderr
# even when no error occurs.
if error_msg.strip('.') == '':
error_msg = ''
return out, error_msg
对于大多数流程,这可以按预期工作
但是现在我必须将它与后台进程一起使用,只要我的python脚本运行也需要继续运行,因此现在有趣的开始;-).
注意:脚本还需要使用相同的_popen-function启动其他非后台进程.
我知道通过跳过p.communicate我可以让进程在后台启动,而我的python脚本继续.
但是这有两个问题:
>我需要检查后台进程是否正确启动
>当主进程正在运行时,我需要不时检查后台进程的stdout和stderr,而不会在后台进程中停止进程/结束.
检查后台进程是否正确启动
对于1我当前调整了_popen版本以获取额外参数’skip_com'(默认为False)以跳过p.communicate调用.在那种情况下,我返回p-object i.s.o. out和error_msg.
这样我就可以检查进程是否在启动后直接运行,如果没有调用p对象上的通信来检查error_msg是什么.
MY_COMMAND_LIST = [ "<command that should go to background>" ]
def _popen( command_list, skip_com=False ):
p = subprocess.Popen( command_list, stdout=subprocess.PIPE,
stderr=subprocess.PIPE )
if not skip_com:
out, error_msg = p.communicate()
# Some processes (e.g. system_start) print a number of dots in stderr
# even when no error occurs.
if error_msg.strip('.') == '':
error_msg = ''
return out, error_msg
else:
return p
...
p = _popen( MY_COMMAND_LIST, True )
error = _get_command_pid( MY_COMMAND_LIST ) # checks if background command is running using _popen and ps -ef
if error:
_, error_msg = p.communicate()
我不知道是否有更好的方法来做到这一点.
检查stdout / stderr
对于2我没有找到一个解决方案,不会导致脚本等待后台进程结束.
我知道沟通的唯一方法是使用iter,例如p.stdout.readline.但是如果进程仍在运行,那将会挂起:
for line in iter( p.stdout.readline, "" ): print line
任何人都知道如何做到这一点?
/ edit /我需要分别从stdout和stderr检查数据.特别是stderr在这种情况下很重要,因为如果后台进程遇到错误,它将退出,我需要在我的主程序中捕获它,以便能够防止该退出导致的错误.
在某些情况下需要stdout输出来检查后台进程中的预期行为并对此作出反应.
解决方法:
更新
The subprocess will actually exit if it encounters an error
如果您不需要读取输出以检测错误,那么redirect it to DEVNULL并调用.poll()来不时检查子进程的状态而不停止进程.
假设您必须阅读输出:
除非从管道中读取,否则不要使用stdout = PIPE,stderr = PIPE.否则,只要任何相应的OS管道缓冲区填满,子进程就可能会挂起.
如果你想在它运行时启动一个进程并做一些其他事情,那么你需要a non-blocking way to read its output.一个简单的可移植方法是使用一个线程:
def process_output(process):
with finishing(process): # close pipes, call .wait()
for line in iter(process.stdout.readline, b''):
if detected_error(line):
communicate_error(process, line)
process = Popen(command, stdout=PIPE, stderr=STDOUT, bufsize=1)
Thread(target=process_output, args=[process]).start()
I need to check the data I get from stdout and stderr seperately.
使用两个线程:
def read_stdout(process):
with waiting(process), process.stdout: # close pipe, call .wait()
for line in iter(process.stdout.readline, b''):
do_something_with_stdout(line)
def read_stderr(process):
with process.stderr:
for line in iter(process.stderr.readline, b''):
if detected_error(line):
communicate_error(process, line)
process = Popen(command, stdout=PIPE, stderr=PIPE, bufsize=1)
Thread(target=read_stdout, args=[process]).start()
Thread(target=read_stderr, args=[process]).start()
您可以将代码放入自定义类(以分组do_something_with_stdout(),detected_error(),communic_error()方法).
内容总结
以上是互联网集市为您收集整理的python – 如何使子进程只传达错误全部内容,希望文章能够帮你解决python – 如何使子进程只传达错误所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。