python - 在实时读取stdout和stderr的同时与子进程交互
问题描述
我需要围绕一个shell命令编写一个包装器,该命令将其stdout和stderr分别实时打印回stdout和stderr,同时如果进程提示输入,还允许用户交互并将stdin发送给它。
请注意,这pexpect.interact()
几乎解决了问题,只是它将所有 stdout 和 stderr 组合在一起并将其发送回 stdout。而且似乎没有办法阻止它这样做。
到目前为止,我所拥有的是一种通过以下方式从进程中读取 stdout 和 stderr 的方法subprocess.Popen
:
def _popen_command(
command: List[str]
) -> None:
"""
Run a shell command with Popen line by line
in real time without redirecting stdout or stderr.
"""
with subprocess.Popen(
command,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
) as proc:
selector = selectors.DefaultSelector()
selector.register(proc.stdout, selectors.EVENT_READ)
selector.register(proc.stderr, selectors.EVENT_READ)
eof = False
while not eof:
for key, _ in selector.select():
data = key.fileobj.read1(1).decode()
if not data:
eof = True
if key.fileobj is proc.stdout:
print(data, end="")
else:
print(data, end="", file=sys.stderr)
我不相信 Stack Overflow 中存在所有这些特性的答案:实时、逐行处理 stdout、stderr,并将它们分别打印回 stdout、stderr,并且还允许与 stdin 进行任意交互。
是否有可能做到这一点?
解决方案
推荐阅读
- vagrant - Aerospike:VBoxManage:错误:无法创建仅主机适配器
- javascript - 通过数组搜索没有结果
- java - JSF 2.2 不呈现或从 javaBean 获取内容
- facebook-graph-api - Facebook 流图实时评论部分有效
- ruby - HTTParty 在 MailChimp 3.0 API 上批量更新用户
- angular - 如何从搜索结果中选择单击的元素并删除 angular4 中的兄弟姐妹
- go - 修复 Go 中的错误连接
- html - 旋转/方向更改后 wkwebview 中的字体大小
- jquery - 获取数据表中的嵌套表行数据
- python - 使用没有类型注释的 mypy 检测类型错误