【发布时间】:2015-12-16 14:23:06
【问题描述】:
我们创建了一个在许多项目中使用的商品函数,它使用子进程来启动命令。这个函数如下:
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 函数启动其他非后台进程。
我知道通过跳过 p.communicate 我可以让进程在后台启动,而我的 python 脚本继续。
但这有两个问题:
- 我需要检查后台进程是否正确启动
- 在主进程运行时,我需要不时检查后台进程的 stdout 和 stderr,而不要停止进程/结束挂在后台进程中。
检查后台进程是否正确启动
对于 1,我目前调整了 _popen 版本以采用额外的参数“skip_com”(默认为 False)来跳过 p.communicate 调用。在那种情况下,我返回 p 对象 i.s.o。出和error_msg。
这样我就可以检查进程是否在启动后直接运行,如果没有调用 p-object 上的通信来检查 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()
我不知道是否有更好的方法来做到这一点。
检查标准输出/标准错误
对于 2,我还没有找到不会导致脚本等待后台进程结束的解决方案。
我知道的唯一交流方式是在例如使用 iter p.stdout.readline。但如果进程仍在运行,这将挂起:
for line in iter( p.stdout.readline, "" ): print line
有人知道怎么做吗?
/edit/ 我需要分别检查从 stdout 和 stderr 获得的数据。在这种情况下,尤其是 stderr 很重要,因为如果后台进程遇到错误,它将退出,我需要在我的主程序中捕获它以防止由该退出导致的错误。
在某些情况下需要 stdout 输出来检查后台进程中的预期行为并对此做出反应。
【问题讨论】:
标签: python subprocess