python子进程模块:循环遍历子进程的stdout

Mat*_*att 5 python subprocess

我有一些使用子进程模块运行的命令.然后我想循环输出的行.文档说不要做data_stream.stdout.read我不是,但我可能正在做一些调用它的东西.我像这样循环输出:

for line in data_stream.stdout:
   #do stuff here
   .
   .
   .
Run Code Online (Sandbox Code Playgroud)

这会导致死锁,例如从data_stream.stdout读取,还是为这种循环设置的Popen模块,以便它使用通信代码但是为你处理它的所有调用?

Ali*_*ell 7

如果你正在与你的子进程通信,你必须担心死锁,即如果你正在写stdin以及从stdout读取.因为这些管道可能被缓存,所以进行这种双向通信是非常禁止的:

data_stream = Popen(mycmd, stdin=PIPE, stdout=PIPE)
data_stream.stdin.write("do something\n")
for line in data_stream:
  ...  # BAD!
Run Code Online (Sandbox Code Playgroud)

但是,如果在构造data_stream时没有设置stdin(或stderr),那么你应该没问题.

data_stream = Popen(mycmd, stdout=PIPE)
for line in data_stream.stdout:
   ...  # Fine
Run Code Online (Sandbox Code Playgroud)

如果您需要双向通信,请使用通信.


Ale*_*lli 6

这两个答案很好地抓住了这个问题的要点:不要把东西写入子进程,从中读取内容,再次写入等等 - 管道的缓冲意味着你有陷入僵局的风险.如果可以,写下你需要写入子进程FIRST的所有内容,关闭该管道,然后只读取子进程必须说的所有内容; communicate很好的目的,如果数据量不是太大,不适合内存(如果是,你仍然可以"手动"达到相同的效果).

如果你需要更细粒度的交互,那么看看pexpect,或者,如果你在Windows上,我们会看到.