在python子进程中检测到封闭的非阻塞stdoutstderr管道。

问题描述 投票:1回答:1

我正在使用Python来交互式地运行一个进程。

p = Popen ("/path/to/my-executable", stdin=PIPE, stdout=PIPE, stderr=PIPE, bufsize=1)

for f in (p.stdout, p.stderr):
    flags = fcntil.fcntl (f, fcntl.F_GETFL) | os.O_NONBLOCK
    fcntl.ftcntl (f, flags)

for line in sys.stdin:
    p.stdin.write (line.encode ('utf-8'))
    ...

假设我从 stdin 读取一条命令并将其转发给 my-executable 通过 p这个进程可能会或不会向stdoutstderr输出任何东西,也可能会或不会终止。

我想等到 my-executable "does something "之前,从stdin读取另一条命令。

我试着用 bash 作为一个子流程和 "exit" 作为 line 写到它的stdin,当我从它的stdout和starr中读取时,stdout给出了 None 和stderr给出了 b'' 但我不认为这是一个可靠的指示,表明一个进程已经完成了运行(也就是说,我不能合理地认为 p.wait() 因为在该结果中没有任何东西能决定性地告诉我,该进程将不再提供任何输出)。)

我如何正确地使这个Python脚本等待到

  • 东西被写入stdout或stderr或
  • stdout或stderr被关闭

?

python subprocess pipe posix
1个回答
0
投票

你可以使用 selectors 来实现,比如这个。

# one-time setup
import selectors
sel = selectors.DefaultSelector()
sel.register(p.stdout, selectors.EVENT_READ)
sel.register(p.stderr, selectors.EVENT_READ)

# each time you want to wait
sel.select()

我建议你使用无缓冲IO,而不是行缓冲IO。另外,您可以使用 os.set_blocking(f.fileno(), False) 以使你的FD是非阻塞的,而不是要搞得一团糟。fcntl 你自己。

© www.soinside.com 2019 - 2024. All rights reserved.