使用 asyncio 子进程时是否可以设置管道的缓冲区大小?
Is it possible to set the buffer size of pipes when using asyncio subprocesses?
我正在编写一个使用
的相当复杂的脚本
asyncio.create_subprocess_exec(sub_cmd, *sub_cmd_args, stdout=PIPE, stderr=PIPE)
环绕另一个 Python 程序——我无法永久修改或以其他方式直接包含——以捕获其 stdout/err 以进行记录。包装的 Python 脚本没有使用 -u
(无缓冲)选项,因此包装程序倾向于登录大缓冲块。如果这是常规 subprocess.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
我认为他们的陷阱是有充分理由的,所以我想知道是否有其他方法可以影响传输缓冲。
我首先向自己证明这确实是一个管道缓冲问题,方法是将 -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'})
这非常有效,感谢我的好朋友和技术专家。
我正在编写一个使用
的相当复杂的脚本asyncio.create_subprocess_exec(sub_cmd, *sub_cmd_args, stdout=PIPE, stderr=PIPE)
环绕另一个 Python 程序——我无法永久修改或以其他方式直接包含——以捕获其 stdout/err 以进行记录。包装的 Python 脚本没有使用 -u
(无缓冲)选项,因此包装程序倾向于登录大缓冲块。如果这是常规 subprocess.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
我认为他们的陷阱是有充分理由的,所以我想知道是否有其他方法可以影响传输缓冲。
我首先向自己证明这确实是一个管道缓冲问题,方法是将 -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'})
这非常有效,感谢我的好朋友和技术专家。