我有一个使用子进程模块打开.exe程序的python脚本。此.exe程序是一个无限迭代的脚本,因为它将继续打印每次迭代的结果,直到用户关闭窗口。它经常会将迭代结果打印到文件中,替换文件中的先前数据。
我的目标是:
这是我目前的代码。它被设计为在创建迭代文件后终止子进程:
import subprocess
from subprocess import Popen, PIPE
fileexists = False
iteratecomms = Popen('iterate.exe', stdout=PIPE, stdin=PIPE, stderr=PIPE)
# Begin the iteration. Need to select options 1 and then 1 again at program menu
out, err = iteratecomms.communicate("1\n1\n".encode())
while (fileexists == False):
fileexists = os.path.exists(filelocation)
else:
Popen.kill(iteratecomms)
我知道这是不正确的;问题是,只要我启动out, err = iteratecomms.communicate("1\n1\n".encode())
行,程序就会开始迭代,而不会转到下一组python代码。本质上,我需要启动.exe程序,同时测试是否已创建该文件。但是,我不能这样做,因为该程序无限期地运行。
我怎么能绕过这个?我假设继续执行第2步(在某些条件下测试文件并杀死子进程)不会在此基础上进行太多工作;如果不是这样,我将如何完成所有目标?
非常感谢您的帮助!
修改:澄清外部文件被覆盖。
答案 0 :(得分:1)
假设您正在尝试不断尝试阅读此文件,我建议您对相关文件运行tail
。这可以通过任何* nix系列操作系统中的单独终端来完成,但是否则我会查看本文以获得Python实现:
http://code.activestate.com/recipes/157035-tail-f-in-python/
之后,如果你想杀死运行的程序,你应该只能在运行的进程上调用terminate:
import subprocess
sub = subprocess.popen(#Whatever)
#Do something
sub.terminate()
答案 1 :(得分:1)
我会使用多处理模块。
pool = multiprocessing.Pool()
def start_iteration():
return Popen('iterate.exe', stdout=PIPE, stdin=PIPE, stderr=PIPE)
pool.apply_async(start_iteration)
while (fileexists == False):
fileexists = os.path.exists(filelocation)
Popen.kill(???)
现在唯一的问题是你必须以某种方式找到进程的PID而不等待Popen返回(因为Popen永远不会返回。)