【问题标题】:Run continuous .exe file with Python使用 Python 运行连续的 .exe 文件
【发布时间】:2017-09-11 22:47:56
【问题描述】:

我正在尝试实现需要运行外部可执行文件的 python 代码。经过一番研究,我找到了subprocess 模块并尝试了它。但是,当我运行代码时,子进程退出并返回一个 CompletedProcess 对象,这对我来说是不行的,因为我正在使用的 .exe 实际上是一个 continuous 程序,它需要输入和在关闭之前生成输出。 (我的程序将发送输入并接收输出。)

所以这段代码失败了。

import subprocess

proc = subprocess.run("some.exe", stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
print(proc) # To see what it is.

它捕获程序首先在标准输出中输出,然后退出,而不是期待新的输入。

我在这里的术语也有问题,我使用的这个可执行文件能够运行命令同时仍然能够接收新命令,这称为 异步 还是 非阻止 ?

我的问题,正确的处理方法是什么?有很多问题与此非常接近,但我不确定哪些是在回答我的问题或以现代方式回答它(​​有非常古老的问题)。

看起来subprocess 模块在 Python 3.6.1 https://docs.python.org/3/library/subprocess.html 中发生了一些变化

因此,最好能以最新的方式提供解决方案,或者至少提及更新的方式及其运作方式。

我正在使用 Windows 10,Python 3.6.1

Edit1:我遇到过subprocess.Popen,这可能是我需要的,但我还没有发现它是如何正确使用的。

Edit2: 模块pexpect 似乎是为这类问题而设计的,但我不确定使用它是否会让我的时间更轻松。任何建议表示赞赏。

【问题讨论】:

  • 这些“输入”能否简单地写入子进程调用的命令中?
  • @JacobIRR,是的,请原谅我没有提及,这是一个控制台应用程序,直接从标准输入接收输入。我可以直接运行它并测试输入,这需要我的 Python 应用程序来代替我来完成。
  • 但是输入不是预先确定的,我一开始调用程序时不能给所有输入。

标签: python python-3.x subprocess


【解决方案1】:

来自文档:

subprocess.run()

运行 args 描述的命令。等待命令完成,然后返回 CompletedProcess 实例。

由于您的子进程在最初调用后并未结束,因此您不能使用run,而是需要使用Popen。

你可以这样使用:

import subprocess
p = subprocess.Popen(exe_path,
                     stdin=subprocess.PIPE, 
                     stdout=subprocess.PIPE,
                     stderr=subprocess.STDOUT)
while p.poll() is None:
    p.stdin.write(some_command)
    p.stdin.flush()
    out = p.stdout.readline()

但请注意,这可能会导致死锁,如documentation 中所述:

警告 使用communicate() 而不是.stdin.write、.stdout.read 或.stderr.read 以避免由于任何其他OS 管道缓冲区填满并阻塞子进程而导致的死锁.

很遗憾,您不能使用communicate,因为这将要求您使用所有输入调用该进程。我会尝试使用上面的版本,看看缓冲区是否真的会导致您的应用程序出现问题。

【讨论】:

  • 感谢您的回答,在您发布答案之前我也遇到了这个问题,这似乎是解决我的问题的唯一简单方法。我只需要将这些包装在某个函数中。但是,我希望能更多地了解这种死锁情况以及如何避免这种情况。
  • 参见here 了解死锁问题的解释。 here 提出的解决方案可能有助于避免死锁,方法是使用单独的线程从缓冲区读取数据以防止填满。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-01
  • 1970-01-01
  • 2015-12-25
  • 2019-12-25
  • 2013-04-02
相关资源
最近更新 更多