通过Python与Windows控制台应用程序进行交互

我在Windows上使用python 2.5。 我希望通过Popen与控制台进程交互。 我目前有这个小的代码片段:

p = Popen( ["console_app.exe"], stdin=PIPE, stdout=PIPE ) # issue command 1... p.stdin.write( 'command1\n' ) result1 = p.stdout.read() # <---- we never return here # issue command 2... p.stdin.write( 'command2\n' ) result2 = p.stdout.read() 

我可以写入标准input,但不能从标准输出读取。 我错过了一个步骤? 我不想使用p.communicate(“command”)[0],因为它终止了进程,我需要随着时间的推移dynamic地与进程交互。

提前致谢。

你的问题在于你试图控制一个交互式应用程序。

stdout.read()将继续读取,直到到达流,文件或管道的末尾。 不幸的是,在交互式程序的情况下,管道只有在程序退出时才关闭。 如果您发送的命令是"quit"以外的其他命令,则永远不会。

您必须使用stdout.readline()逐行读取子stdout.readline()的输出,并且最好有一种方法来告诉程序何时准备好接受命令,并且当您发出的命令到程序完成,你可以提供一个新的。 在像cmd.exe这样的程序的情况下,即使readline()也不行,因为指示可以发送新命令的行不会被换行符终止,所以必须逐字节地分析输出。 下面是运行cmd.exe的示例脚本,查找提示符,然后发出一个dir然后exit

 from subprocess import * import re class InteractiveCommand: def __init__(self, process, prompt): self.process = process self.prompt = prompt self.output = "" self.wait_for_prompt() def wait_for_prompt(self): while not self.prompt.search(self.output): c = self.process.stdout.read(1) if c == "": break self.output += c # Now we're at a prompt; clear the output buffer and return its contents tmp = self.output self.output = "" return tmp def command(self, command): self.process.stdin.write(command + "\n") return self.wait_for_prompt() p = Popen( ["cmd.exe"], stdin=PIPE, stdout=PIPE ) prompt = re.compile(r"^C:\\.*>", re.M) cmd = InteractiveCommand(p, prompt) listing = cmd.command("dir") cmd.command("exit") print listing 

如果时间不重要,并且用户的交互性不是必需的,那么调整呼叫可能会简单得多:

 from subprocess import * p = Popen( ["cmd.exe"], stdin=PIPE, stdout=PIPE ) p.stdin.write("dir\n") p.stdin.write("exit\n") print p.stdout.read() 

你有没有试图强制Windows结束?

 p.stdin.write( 'command1 \r\n' ) p.stdout.readline() 

更新:

我刚刚在windows cmd.exe上检查了解决方案,它与readline()一起使用。 但是Popen的stdout.readline 有一个问题。 所以如果应用程序将永远返回一些没有endline的应用程序将永久卡住。

但有一个工作,检查出来: http : //code.activestate.com/recipes/440554/

我想你可能想尝试使用readline()来代替?

编辑:对不起,误会了。

也许这个问题可以帮助你?

控制台应用程序是否有可能以某种方式缓冲其输出,以便在管道关闭时仅将其发送到标准输出? 如果您有权访问控制台应用程序的代码,也许在一批输出数据可能有帮助后进行刷新?

或者,它实际上写入标准错误,而不是标准出于某种原因?

只是再次查看你的代码,并想到其他的东西,我看到你正在发送“command \ n”。 控制台应用程序可以简单地等待一个回车符而不是一个新的行吗? 也许控制台应用程序正在等待您提交命令之前,它会产生任何输出。

在这里有完全相同的问题。 我挖了DrPython的源代码,并偷走了wx.Execute()解决方案,这工作正常,特别是如果您的脚本已经使用wx。 我从来没有在Windows平台上找到正确的解决方案…