是否可以将subprocess.Popen的stdout重新连接到sys.stdout? (python3)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了是否可以将subprocess.Popen的stdout重新连接到sys.stdout? (python3)相关的知识,希望对你有一定的参考价值。

我有一个使用popen运行另一个程序的python程序。是否有可能从程序的输出读取一段时间,并将子程序的输出连接到sys.stdout,并允许它并行运行,就像我在没有stdout=subprocess.PIPE选项的情况下启动它一样?

包装:

#! /usr/bin/env python3

import subprocess
from time import sleep
import sys

p = subprocess.Popen(
  ["./count.py"],
  stdout=subprocess.PIPE,
)

for line in iter(p.stdout.readline,''):
  l = line.decode('utf-8')
  sys.stdout.write(">>" + l)
  if "8" in l:
    # somehow reconnect p.stdout to sys.stdout
    break

sleep(1)

print("now do some stuff in parallel")

sleep(1)

p.terminate()

测试程序:

#! /usr/bin/env python

from time import sleep
import sys

for x in range(1,100):
  sleep(.1)
  print x
  sys.stdout.flush()

输出:

$ ./wrapper.py
>>1
>>2
>>3
>>4
>>5
>>6
>>7
>>8
now do some stuff in parallel

是否有可能做到这一点?

$ ./wrapper.py
>>1
>>2
...
>>7
>>8
9
10
...
18
19
now do some stuff in parallel
20
21
...
28
29
答案

您不能“重新连接”已经启动的子进程的文件描述符(除非非常脏和特定于操作系统的技巧)。您可以控制的唯一文件描述符是仍在您的过程中的文件描述符,它只对读取有用。因此,如果你想要进入stdout,那么进入read端的所有内容都必须以某种方式复制到stdout。

幸运的是,您总是可以生成另一个子进程来执行此操作。这就是方便的Unix实用程序cat做得很好的事情。

subprocess.Popen(
  ["/bin/cat"],
  stdin=p.stdout,
)

这将基本上创建一个管道,您可以将一个流程的输出传输到另一个流程。它非常有用。在这种情况下,其他进程(cat)只输出到stdout。

以上是关于是否可以将subprocess.Popen的stdout重新连接到sys.stdout? (python3)的主要内容,如果未能解决你的问题,请参考以下文章

Subprocess.Popen:将 stdout 和 stderr 克隆到终端和变量

管道输出subprocess.Popen到文件

Popen:python 2和3之间的区别

subprocess.Popen与CLI提示交互

“subprocess.Popen” - 检查成功和错误

subprocess.call和subprocess.Popen