在python中包装交互式CLI
我正在尝试用python脚本进行包装 我已经在SO中讨论了关于包装CLI应用程序的其他问题,尽管这些问题有所帮助,但我还未能使脚本完全正常工作。在stdin的第一次输入之后,进程似乎被终止 脚本如下所示:在python中包装交互式CLI,python,popen,Python,Popen,我正在尝试用python脚本进行包装 我已经在SO中讨论了关于包装CLI应用程序的其他问题,尽管这些问题有所帮助,但我还未能使脚本完全正常工作。在stdin的第一次输入之后,进程似乎被终止 脚本如下所示: import subprocess proc = subprocess.Popen(['gnugo', '--mode', 'gtp'], stdout=subprocess.PIPE, stdin=subprocess.PIPE) c = raw_input('first comman
import subprocess
proc = subprocess.Popen(['gnugo', '--mode', 'gtp'], stdout=subprocess.PIPE, stdin=subprocess.PIPE)
c = raw_input('first command: ')
while True:
r = proc.communicate(c)
print 'gnugo says: ' + str(r)
c = raw_input('next command: ')
我得到的错误是:
$ python testgnu.py
first command: play b c4
gnugo says: ('= \n\n', None)
next command: genmove w
Traceback (most recent call last):
File "testgnu.py", line 8, in <module>
r = proc.communicate(c)
File "/usr/local/Cellar/python/2.7.3/lib/python2.7/subprocess.py", line 754, in communicate
return self._communicate(input)
File "/usr/local/Cellar/python/2.7.3/lib/python2.7/subprocess.py", line 1307, in _communicate
self.stdin.flush()
ValueError: I/O operation on closed file
$python testgnu.py
第一个命令:播放b c4
gnugo说:('=\n\n',无)
下一个命令:genmove w
回溯(最近一次呼叫最后一次):
文件“testgnu.py”,第8行,在
r=过程通信(c)
文件“/usr/local/cillar/python/2.7.3/lib/python2.7/subprocess.py”,第754行,在communicate中
返回自我。\u通信(输入)
文件“/usr/local/ceral/python/2.7.3/lib/python2.7/subprocess.py”,第1307行,在
self.stdin.flush()
ValueError:对关闭的文件执行I/O操作
我运行的是Python2.7.3(可能没关系,但gnugo版本是3.8)
其他问题中的一些答案是建议的,但我希望使用尽可能少的外部库。您的问题是在执行读写操作后关闭文件
您必须手动调用proc.stdin.write(…)
来发送流程文本,而proc.stdout.read*()
来读取文本:
while True:
proc.stdin.write(c)
r = proc.stdout.readline()
是的,我想就是这样。现在stdout.read()挂起,不过这似乎是另一个问题。谢谢
stdout.read()
将挂起,因为.read()
尝试读取所有输出。相反,请使用.readline()
(在我的示例中),它一次只读取一行,或者使用.read(n)
,它将读取(最多)n
字节。问题似乎在于它从未收到EOF,因此它从未终止gnugo
在玩家移动时几乎立即返回。我试图显式地将\n
写入stdin,但它看起来至少让readline()
通过一次(如果我不将\n
写入stdin,它将挂起),但是read()
仍然挂起。为什么要直接调用read()
?您只需调用.readline()
…否?readline()
也将挂起。我可以给stdin传递一堆新行,然后把它们上传到readline()。目前,我不太明白为什么将换行符添加到stdin缓冲区的末尾会使readline()
多次工作(每次我从stdout获得更多我想要的数据-而不仅仅是您可能期望的空换行符)。我不介意做readline()
,只要它最终不会挂起。