2016-10-10 29 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

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