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

2024-06-01 08:01:32 发布

您现在位置:Python中文网/ 问答频道 /正文

我在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()

我可以给stdin写信,但不能从stdout读。我错过了一步吗?我不想使用p.communicate(“command”)[0],因为它终止了进程,我需要随着时间的推移与进程动态交互。

提前谢谢。


Tags: 代码appread进程windowsstdinstdoutissue
3条回答

我想您可能想改为使用readline()?

编辑:对不起,误会了。

或许this问题能帮到你?

你有没有试过强迫窗口结束线? i、 e

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

更新:

我刚刚检查了windows cmd.exe上的解决方案,它可以与readline()一起使用。但Popen的stdout.readline块有一个问题。因此,如果应用程序返回的东西没有结束线,你的应用程序将永远卡住。

但是有一个办法可以解决这个问题:http://code.activestate.com/recipes/440554/

这里的问题是您试图控制一个交互式应用程序。

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

您必须使用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()

相关问题 更多 >