【问题标题】:Simple Windows example of automating a .exe program using subprocess and .Popen使用子进程和 .Popen 自动化 .exe 程序的简单 Windows 示例
【发布时间】:2013-07-12 14:24:52
【问题描述】:

我是 subprocess 模块的新手,在阅读了许多其他网站(包括 Stack Overflow)中的 Python documents 之后,我很难找到 .Popen.communicate 和其他此类有用类的简化示例。通常,这些示例从不连续使用每个类,只是单独使用。另外,很多例子都是基于Linux的,比如["ls", "-l"]的使用,对于Windows用户来说比较难理解。

在玩了这个模块几个小时后,我遇到了几个问题,最好通过一个简单的.exe命令行程序打开和通信的方法来说明。

例如,假设程序名为“numbers.exe”,它会询问以下问题:

>>> Question 1) Choose 1, 2 or 3
>>> Question 2) Choose 4, 5 or 6
>>> You have answered #(Q1) and #(Q2)
>>> *Use these values in an iterative sequence displaying each stage in the iteration*

然后我想自动操作这个程序,即我希望 python 输入 2 和 6 而无需我做任何事情,但仍然打印问题。然后我希望能够在 python 中查看迭代。

这里首先考虑的是我可以使用:

from subprocess import Popen, PIPE

numprog = subprocess.call('numbers.exe')
print(numprog.communicate())

但是,这只是打开程序,我仍然需要自己输入 2 和 6。为了自动化这个过程,我相信我必须使用Popen,以及标准输入、标准输出和标准错误。这是我遇到问题的地方。我知道我必须使用 Popen 开始与输入 (stdin)、输出 (stdout) 和错误 (stderr) 管道进行通信:

from subprocess import Popen, PIPE

numcomms = Popen('numbers.exe', stdout=PIPE, stdin=PIPE, stderr=PIPE)

我不确定从这里做什么。使用numcomms.stdout.read() 会导致程序停留,使用numcomms.stdin.write(2) 会抛出无法使用int 值的错误。 numprog.communicate 类似乎要求您自己输入值。

据我所知,伪代码大致如下:

>>> Open numbers.exe stdin, stdout and stderr pipes using Popen
>>> Print first question using stdout
>>> Enter "2" using stdin
>>> Print second question using stdout
>>> Enter "6" using stdin
>>> Receive a string saying "You have answered 2 and 6" using stdout
>>> Display the results of each stage of the iteration using stdout

我该如何写这篇文章?

非常感谢您的帮助,谢谢!

编辑:编辑问题以描述迭代序列问题。 Michael 为输入问题提出了一个很好的解决方案,但是我在打印迭代结果时遇到了麻烦。

【问题讨论】:

    标签: python subprocess stdout stdin stderr


    【解决方案1】:

    subprocess.stdin.write 的问题可能是您需要提供字符串而不是整数,正如 Steve Barnes 正确指出的那样。

    但是,对于您的简单情况,它们可能是一个更简单的解决方案。 communicate 方法有一个可选的输入参数,所以应该可以:

    from subprocess import Popen, PIPE
    
    numcomms = Popen('numbers.exe', stdout=PIPE, stdin=PIPE, stderr=PIPE)
    out, err = numcomms.communicate("2\n6\n")
    

    程序的输出应该在out之后,并且可以很容易地使用out.splitlines()进行拆分。

    【讨论】:

    • 我尝试使用字符串作为写入函数;那也没有用。不幸的是,如果我使用 out, err = numcomms.communicate("2\n6\n") 解决方案,我会得到同样的错误。错误状态“'str' 不支持缓冲区接口”。谢谢你的建议!
    • 您使用的是 Python 3.x 吗?在这种情况下,您需要对字符串进行编码。在这种情况下尝试使用numcomms.communicate("2\n6\n".encode())
    • 谢谢,不再报错;但是我现在遇到了打印问题!完全是我的错;我忘了提到 .exe 程序在一个迭代循环中使用这些数字,并无限期地显示循环中的每个阶段。当我使用您建议的代码时,光标只是停留在屏幕上并且不打印任何内容,这表明迭代正在工作,但 python 代码没有打印结果。你对此有什么建议吗?非常感谢您的耐心等待!
    • +1 - 很好的例子,如何与命令提示符/终端交互
    【解决方案2】:

    我认为您对 subprocess.stdin.write 的问题是程序将期望一个字符串可能以换行符终止,即 '2\n' 而不是 int。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-02-11
      • 1970-01-01
      • 2013-03-08
      • 1970-01-01
      • 2012-09-18
      • 2017-07-24
      • 2012-01-11
      相关资源
      最近更新 更多