我正在使用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 读取命令并通过p
将其转发给my-executable
,这个过程可能会也可能不会向 stdout/stderr 输出任何内容,并且可能会也可能不会终止。
我想等到my-executable
"做某事",然后再从 stdin 读取另一个命令。
我尝试将bash
作为子进程,"exit"
作为写入其 stdinline
,当我从它的 stdout 和 sterr 中读取时,stdout 给出了None
,stderr 给出了b''
但我不认为这是一个可靠的指示,表明一个进程已经完成运行(即我无法合理地p.wait()
因为该结果中没有任何内容可以决定性地告诉我该过程不会给出任何更多输出(。
如何正确使此 Python 脚本等到
- 某些内容被写入 stdout 或 stderr 或 标准输出
- 或标准输出已关闭
?
您可以使用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()
不过,我建议您使用无缓冲的 I/O,而不是行缓冲的 I/O。此外,您可以做os.set_blocking(f.fileno(), False)
使您的 FD 不阻塞,而不必自己弄乱fcntl
。