2015-06-30 33 views
4

我正在寫一個使用使用asyncio子進程時可以設置管道的緩衝區大小嗎?

asyncio.create_subprocess_exec(sub_cmd, *sub_cmd_args, stdout=PIPE, stderr=PIPE) 

環繞另一個Python程序相當複雜的腳本 - 我不能永久地修改或以其他方式包括直接 - 捕捉要記錄它的標準輸出/犯錯。包裝的Python腳本不使用-u(無緩衝)選項,因此包裝程序傾向於登錄大緩衝區塊。如果這是常規的子進程.Popen,我可以通過bufsize=1得到我想要的,即行緩衝。但是,如果我再補充一點,以asyncio.create_subprocess_exec(),他們的陷阱專門和我得到:

<snip> 
    File "/usr/lib64/python3.4/asyncio/subprocess.py", line 193, in create_subprocess_exec 
    stderr=stderr, **kwds) 
    File "/usr/lib64/python3.4/asyncio/base_events.py", line 642, in subprocess_exec 
    raise ValueError("bufsize must be 0") 
ValueError: bufsize must be 0 

我認爲他們的陷阱是有很好的理由,所以我不知道是否有一些其他的方式,我可以影響運輸緩衝。

回答

1

我第一次向自己證明,這是一個真正的管道緩衝問題,將-u添加到包裝程序的shebang行中。我不能依靠這個解決方案,因爲這樣的改變最終會被OS更新所破壞。

我能夠以類似的方式,雖然解決了問題,但:

  • 的包裝程序是管道的父程序,所以它控制它的子計劃的環境。
  • Python應該在其繼承的環境中服從PYTHONUNBUFFERED=1
  • asyncio.create_subprocess_exec()確實支持env=參數和其他大部分可以傳遞給subprocess.Popen()的所有其他信息;也許有點文件不足,但看看代碼使得這很明顯。

所以我改變了我的呼籲:

asyncio.create_subprocess_exec(sub_cmd, *sub_cmd_args, stdout=PIPE, stderr=PIPE, env={'PYTHONUNBUFFERED': '1'}) 

這完美地工作,並歸功於我的好朋友和技術大師。