2016-10-10 28 views
2

我想用python的asyncio模块跟踪守护进程的重启进程。所以我需要运行shell命令tail -f -n 0 /var/log/daemon.log并分析它的输出,比方说,service daemon restart在后台执行。守护进程在服务重新启动命令完成执行后继续写入日志并报告它是内部检查。跟踪进程读取检查信息,并根据内部逻辑报告重新启动成功与否。如何使用asyncio复杂地管理shell进程?

import asyncio 
from asyncio.subprocess import PIPE, STDOUT 

async def track(): 
    output = [] 
    process = await asyncio.create_subprocess_shell(
     'tail -f -n0 ~/daemon.log', 
     stdin=PIPE, stdout=PIPE, stderr=STDOUT 
    ) 
    while True: 
     line = await process.stdout.readline() 
     if line.decode() == 'reboot starts\n': 
      output.append(line) 
      break 
    while True: 
     line = await process.stdout.readline() 
     if line.decode() == '1st check completed\n': 
      output.append(line) 
      break 
    return output 

async def reboot(): 
    lines = [ 
     '...', 
     '...', 
     'reboot starts', 
     '...', 
     '1st check completed', 
     '...', 
    ] 
    p = await asyncio.create_subprocess_shell(
     (
      'echo "rebooting"; ' 
      'for line in {}; ' 
       'do echo $line >> ~/daemon.log; sleep 1; ' 
      'done; ' 
      'echo "rebooted";' 
     ).format(' '.join('"{}"'.format(l) for l in lines)), 
     stdin=PIPE, stdout=PIPE, stderr=STDOUT 
    ) 
    return (await p.communicate())[0].splitlines() 

if __name__ == '__main__': 
    loop = asyncio.get_event_loop() 
    loop.run_until_complete(asyncio.gather(
     asyncio.ensure_future(track()), 
     asyncio.ensure_future(reboot()) 
    )) 
    loop.close() 

这段代码是我发现并行运行两个协程的唯一方法。但是如何在reboot之前严格运行track()才不会错过log中的任何可能输出?以及如何检索两个协程的返回值?

回答

1

但如何在重新启动前严格运行track()以不会错过log中的任何可能输出?

您可以在运行第二个子程序之前创建第一个子程序。

以及如何检索两个协程的返回值?

asyncio.gather返回汇总结果。

例子:

async def main(): 
    process_a = await asyncio.create_subprocess_shell([...]) 
    process_b = await asyncio.create_subprocess_shell([...]) 
    return await asyncio.gather(monitor_a(process_a), monitor_b(process_b)) 

loop = asyncio.get_event_loop() 
result_a, result_b = loop.run_until_complete(main()) 
+0

究竟是什么,我的意思! –