我用下面的命令启动一个子进程:
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
然而,当我试图杀死使用:
p.terminate()
or
p.kill()
该命令一直在后台运行,因此我想知道如何实际终止该进程。
注意,当我使用以下命令运行时:
p = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE)
它在发出p.terminate()时成功终止。
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
p.kill()
P.kill()最终杀死shell进程,CMD仍在运行。
我找到了一个方便的解决方法:
p = subprocess.Popen("exec " + cmd, stdout=subprocess.PIPE, shell=True)
这将导致cmd继承shell进程,而不是让shell启动一个子进程,这不会被杀死。P.pid将是您的CMD进程的id。
P.kill()应该工作。
我不知道这会对你的烟斗有什么影响。
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
p.kill()
P.kill()最终杀死shell进程,CMD仍在运行。
我找到了一个方便的解决方法:
p = subprocess.Popen("exec " + cmd, stdout=subprocess.PIPE, shell=True)
这将导致cmd继承shell进程,而不是让shell启动一个子进程,这不会被杀死。P.pid将是您的CMD进程的id。
P.kill()应该工作。
我不知道这会对你的烟斗有什么影响。
使用进程组,以便向该组中的所有进程发送信号。为此,您应该将会话id附加到派生/子进程的父进程,在您的示例中是一个shell。这将使它成为流程的组领导者。所以现在,当一个信号被发送到进程组领导时,它就被传输到该组的所有子进程。
代码如下:
import os
import signal
import subprocess
# The os.setsid() is passed in the argument preexec_fn so
# it's run after the fork() and before exec() to run the shell.
pro = subprocess.Popen(cmd, stdout=subprocess.PIPE,
shell=True, preexec_fn=os.setsid)
os.killpg(os.getpgid(pro.pid), signal.SIGTERM) # Send the signal to all the process groups
正如Sai所说,shell是子程序,所以信号会被它拦截——我发现的最好的方法是使用shell=False并使用shlex来分割命令行:
if isinstance(command, unicode):
cmd = command.encode('utf8')
args = shlex.split(cmd)
p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
那么p.kill()和p.terminate()应该按您期望的方式工作。