从subprocess.Popen.stdout读取多行

时间:2010-10-08 18:53:31

标签: python subprocess

我修改了Fred Lundh的Python标准库中的源代码。 原始源使用popen2与子进程通信,但我将其更改为使用subprocess.Popen(),如下所示。

import subprocess
import string

class Chess:
    "Interface class for chesstool-compatible programs"

    def __init__(self, engine = "/opt/local/bin/gnuchess"):
        proc=subprocess.Popen([engine],stdin=subprocess.PIPE,stdout=subprocess.PIPE)
        self.fin, self.fout = proc.stdin, proc.stdout

        s = self.fout.readline() <--
        print s
        if not s.startswith("GNU Chess"):
            raise IOError, "incompatible chess program"

    def move(self, move):
        ...
        my = self.fout.readline() <--
        ...

    def quit(self):
        self.fin.write("quit\n")
        self.fin.flush()

g = Chess()
print g.move("a2a4")
print g.move("b2b3")
g.quit()

它似乎运行正常,但gnuchess打印出多行消息,如下所示,但使用self.fout.readline()它只显示一行。

Thinking...
... 
R N B Q K B N R 

如何获得多行信息? readlines()方法似乎不起作用。

ADDED

我测试了movieyoda的代码,但它不起作用。 我认为只有readline()应该工作,而不是readlines()和read()是正确的,因为除了readline()之外,不知道何时停止读取。

2 个答案:

答案 0 :(得分:2)

要与gnuchess互动,我会使用pexpect

import pexpect
import sys
game = pexpect.spawn('/usr/games/gnuchess')
# Echo output to stdout
game.logfile = sys.stdout
game.expect('White')
game.sendline('a2a4')
game.expect('White')
game.sendline('b2b3')
game.expect('White')
game.sendline('quit')

答案 1 :(得分:0)

我会在它到达时读取它的输出。当进程终止时,子进程模块将负责为您清理。你可以这样做 -

l = list()
while True:
    data = proc.stdout.read(4096)
    if not data:
        break
    l.append(data)
file_data = ''.join(l)

所有这些都是self.fout.readline()的替代品。没试过。但是应该处理多行。