监视从windows中的shell命令创建的子进程

时间:2017-01-24 21:17:01

标签: python windows shell subprocess

我正在使用subprocess.Popen

打开一个程序

import subprocess

prog = subprocess.Popen(['myprog', args], shell=True)

我想监控这个过程' myprog'并等待直到我的代码继续之前它终止。

我面临的问题是prog.pid是shell的PID而不是myprog'我不知道如何获得'myprog'的PID。我尝试使用psutil查找prog.pid的子进程:

parent = psutil.Process(prog.pid)
children = parent.children(recursive=True)

但返回一个空列表。

不幸的是我无法启动myprog'没有壳。当我使用shell=False运行命令时,收到以下错误消息: FileNotFoundError: [WinError 2] The system cannot find the file specified

我搜索网络的高低,但所有有前途的潜在客户都是非Windows用户。

1 个答案:

答案 0 :(得分:1)

您的atom命令可能是.cmd文件,用于启动可执行文件,这解释了对shell=True

的需求

你不会在python中重新编码.bat文件,但你也不需要可执行的PID。

如果可执行文件结束,批处理文件结束,所以忘记监视prog.pid,只使用prog监视poll(当然在同一个python脚本中)。

poll方法允许检查进程是否已经结束(如果有,则返回退出代码,如果它没有返回None),这是非阻塞的,所以你可以随时随地做到这一点:

if prog.poll() is not None:
    # process has ended
    print("ended")

让我们提醒阻止等待:

return_code = prog.wait()

但在您的情况下,atom.cmd命令似乎在后台启动该过程,因此无法在没有PID的情况下进行监视。

在这种情况下,解决方法是制作atom.cmd的副本,删除start前缀以在前台运行可执行文件并改为运行副本。

(或者,当cmd调用另一个atom.cmd文件时,从app-1.13.0\resources\cli\atom.cmd原始目录中找到文件atom.cmd并删除start前缀)