python子进程交互,为什么我的进程使用Popen.communicate,而不使用Popen.stdout.read()?
问题描述
我正在尝试使用 subprocess
模块与使用 Python 的命令行聊天机器人进行通信.(http://howie.sourceforge.net/使用编译好的win32二进制,我有我的理由!)
I am trying to communicate with a command-line chat bot with Python using the subprocess
module. (http://howie.sourceforge.net/ using the compiled win32 binary, I have my reasons!)
这行得通:
proc = Popen('Howie/howie.exe', stdout=PIPE,stderr=STDOUT,stdin=PIPE)
output = proc.communicate()
但 Popen.communicate
等待进程终止(并将其发送 EOF?),我希望能够与之交互.明显的解决方案是像这样读取 stdout
/写入 stdin
:
But Popen.communicate
waits for the process to terminate (and sends it EOF?), I want to be able to interact with it. The apparent solution for this was to read stdout
/ write stdin
like so:
这不起作用:
proc = Popen('Howie/howie.exe', stdout=PIPE,stderr=STDOUT,stdin=PIPE)
while True: print proc.stdout.readline()
(请注意,我实际上使用的是基于 http://code.activestate.com 的更复杂的代码/recipes/440554/ 但问题是一样的.)
(Note that I am actually using more complex code based on http://code.activestate.com/recipes/440554/ but the issue is the same.)
问题是,第二种方法非常适合与 cmd 通信,但是当我运行聊天机器人时,什么也没有.所以我的问题是,捕获输出与使用 Popen.communicate() 有何不同?
The problem is, the second approach works perfectly for communicating to cmd, but when I run the chatbot, nothing. So my question is, how is this different in capturing output to using Popen.communicate()?
即我可以使用第二种方法照常使用命令行,直到我运行聊天机器人,此时我停止接收输出.使用第一种方法可以正确显示机器人的前几行输出,但我无法与之交互.
i.e. I can use the second approach to use the command line as per normal, until I run the chatbot, at which point I stop receiving output. Using the first approach correctly displays the first few lines of output from the bot, but leaves me unable to interact with it.
解决方案
两者的一个主要区别是communicate()在发送数据后关闭stdin.我不知道你的具体情况,但在很多情况下,这意味着如果一个进程正在等待用户输入的结束,他会在使用communicate() 时得到它,而当代码阻塞时永远不会得到它read() 或 readline().
One major difference between the two is that communicate() closes stdin after sending the data. I don't know about your particular case, but in many cases this means that if a process is awaiting the end of the user input, he will get it when communicate() is used, and will never get it when the code blocks on read() or readline().
先尝试添加 Popen.stdin.close() 看看它是否会影响您的情况.
Try adding Popen.stdin.close() first and see if it affects your case.
相关文章