使用子进程与程序反复交互
我正在尝试运行一个需要连续互动的程序(我需要用字符串'0'或'1'来回答)。
我的代码:
from subprocess import Popen, PIPE
command = ['program', '-arg1', 'path/file_to_arg1']
p = Popen(command, stdin=PIPE, stdout=PIPE)
p.communicate('0'.encode())
最后两行代码在第一次互动时能正常工作,但之后程序会把所有后续的问题都打印出来,而不等我输入答案。其实我需要的是先回答第一个问题,等程序处理完这个问题并打印出第二个问题后,再回答第二个问题,依此类推。
有没有什么好的建议?谢谢!
PS:我使用的是Python 3.3.4
2 个回答
0
如果你想要实时捕捉子进程的标准输出,可以看看这个讨论帖:实时捕捉子进程的标准输出
1
subprocess模块是为了单次交互而设计的。也就是说,你可以向一个进程发送信息,然后读取结果,之后就结束了。要实现与Unix进程之间持续的来回互动,比如不断地读写信息,这就比较困难。我建议使用专门为这个任务设计的库,而不是从头开始重新编写所有必要的逻辑。
有一个经典的库叫做 Expect,它在与子进程交互时表现得很好。还有一个Python实现版本叫做 Pexpect(你可以在 这里 阅读文档)。我推荐使用Pexpect或者类似的库。
Pexpect的工作原理是这样的:
# spawn a subprocess.
# then wait for expected output from the child process,
# and send additional commands to the child.
child = pexpect.spawnu('ftp ftp.openbsd.org')
child.expect('(?i)name .*: ')
child.sendline('anonymous')
child.expect('(?i)password')
child.sendline('pexpect@sourceforge.net')
child.expect('ftp> ')
child.sendline('cd /pub/OpenBSD/3.7/packages/i386')
child.expect('ftp> ')