我用下面的命令启动一个子进程:

p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)

然而,当我试图杀死使用:

p.terminate()

or

p.kill()

该命令一直在后台运行,因此我想知道如何实际终止该进程。

注意,当我使用以下命令运行时:

p = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE)

它在发出p.terminate()时成功终止。


当前回答

我可以用

from subprocess import Popen

process = Popen(command, shell=True)
Popen("TASKKILL /F /PID {pid} /T".format(pid=process.pid))

它杀死了cmd.exe和我命令的程序。

(在Windows上)

其他回答

我可以用

from subprocess import Popen

process = Popen(command, shell=True)
Popen("TASKKILL /F /PID {pid} /T".format(pid=process.pid))

它杀死了cmd.exe和我命令的程序。

(在Windows上)

向组中的所有进程发送信号

    self.proc = Popen(commands, 
            stdout=PIPE, 
            stderr=STDOUT, 
            universal_newlines=True, 
            preexec_fn=os.setsid)

    os.killpg(os.getpgid(self.proc.pid), signal.SIGHUP)
    os.killpg(os.getpgid(self.proc.pid), signal.SIGTERM)

当shell=True时,shell是子进程,命令是它的子进程。因此,任何SIGTERM或SIGKILL都会杀死shell,但不会杀死它的子进程,我不记得有什么好方法可以做到这一点。 我能想到的最好的方法是使用shell=False,否则当你杀死父shell进程时,它将留下一个失效的shell进程。

这些答案都没有为我工作,所以我离开了工作的代码。在我的例子中,即使在用.kill()杀死进程并获得.poll()返回代码之后,进程也没有终止。

遵循子流程。Popen文档:

"...为了正确地清理,一个行为良好的应用程序应该杀死子进程并完成通信……”

proc = subprocess.Popen(...)
try:
    outs, errs = proc.communicate(timeout=15)
except TimeoutExpired:
    proc.kill()
    outs, errs = proc.communicate()

在我的情况下,我在调用proc.kill()后错过了proc. communication()。这将清除进程stdin, stdout…并且终止了这个过程。

这个方法对我很有效

if os.name == 'nt':  # windows
    subprocess.Popen("TASKKILL /F /PID {pid} /T".format(pid=process.pid))
else:
    os.kill(process.pid, signal.SIGTERM)