使用Python

时间:2017-04-16 00:18:55

标签: python python-3.x subprocess

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

所以这段代码失败了。

import subprocess

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

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

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

对我的问题,处理此问题的正确方法是什么?在这方面有很多问题,但是我无法确定哪个问题能够回答我的问题或以现代的方式回答它(​​有很多问题)。

使用Python 3.6.1 https://docs.python.org/3/library/subprocess.html

看来subprocess模块会发生一些变化

因此,如果您能够以最新的方式提供解决方案,或者至少提及更新的方式及其运作方式,那将是最好的。

我正在使用Windows 10,Python 3.6.1

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

编辑2:模块pexpect似乎是针对这类问题设计的,但我不确定是否使用此功能可以让我的时间更轻松。任何建议表示赞赏。

1 个答案:

答案 0 :(得分: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

中描述的死锁
  

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

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