Estou iniciando um subprocesso com o seguinte comando:
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
No entanto, quando tento matar usando:
p.terminate()
ou
p.kill()
O comando continua sendo executado em segundo plano, então eu queria saber como posso realmente finalizar o processo.
Observe que quando executo o comando com:
p = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE)
Ele termina com êxito ao emitir o arquivo p.terminate()
.
python
linux
subprocess
kill-process
user175259
fonte
fonte
cmd
aparência? Pode conter um comando que aciona vários processos a serem iniciados. Portanto, não está claro de qual processo você fala.shell=True
faz uma grande diferença?Respostas:
Use um grupo de processos para permitir o envio de um sinal para todo o processo nos grupos. Para isso, você deve anexar uma identificação de sessão ao processo pai dos processos gerados / filhos, que é um shell no seu caso. Isso o tornará o líder do grupo nos processos. Portanto, agora, quando um sinal é enviado ao líder do grupo de processos, ele é transmitido a todos os processos filhos desse grupo.
Aqui está o código:
fonte
os.setsid
não está disponível no Windows ( docs.python.org/library/os.html#os.setsid ), não sei se isso pode ajudar, mas você pode procurar aqui ( bugs.python.org / issue5115 ) para obter algumas dicas sobre como fazê-lo.subprocess.CREATE_NEW_PROCESS_GROUP
relaciona com isso?CREATE_NEW_PROCESS_GROUP
pode ser usado para emularstart_new_session=True
no Windowsp.kill()
acaba matando o processo do shell ecmd
ainda está em execução.Encontrei uma correção conveniente por:
Isso fará com que o cmd herde o processo do shell, em vez de o shell iniciar um processo filho, que não é morto.
p.pid
será o ID do seu processo de cmd então.p.kill()
Deveria trabalhar.Não sei que efeito isso terá no seu cachimbo.
fonte
Se você pode usar o psutil , isso funciona perfeitamente:
fonte
AttributeError: 'Process' object has no attribute 'get_children
parapip install psutil
.Eu poderia fazer isso usando
matou o
cmd.exe
programa que eu dei o comando.(No Windows)
fonte
Popen("TASKKILL /F /IM " + process_name)
se você não o tiver, poderá obtê-lo a partir docommand
parâmetroQuando
shell=True
o shell é o processo filho e os comandos são seus filhos. Portanto, qualquer umSIGTERM
ouSIGKILL
matará o shell, mas não seus processos filhos, e não me lembro de uma boa maneira de fazê-lo. A melhor maneira de pensar é usarshell=False
, caso contrário, quando você mata o processo de shell pai, ele deixa um processo de shell desativado.fonte
Nenhuma dessas respostas funcionou para mim, então estou deixando o código que funcionou. No meu caso, mesmo depois de encerrar o processo
.kill()
e obter uma.poll()
encerrar código de retorno, o processo não foi encerrado.Seguindo a
subprocess.Popen
documentação :No meu caso, estava faltando a
proc.communicate()
chamada depoisproc.kill()
. Isso limpa o processo stdin, stdout ... e encerra o processo.fonte
Como Sai disse, o shell é o filho, então os sinais são interceptados por ele - a melhor maneira que eu encontrei é usar shell = False e usar shlex para dividir a linha de comando:
Então p.kill () e p.terminate () devem funcionar como você espera.
fonte
cwd
argumento paraPopen
.o que eu sinto que poderíamos usar:
isso não matará toda a sua tarefa, mas o processo com o p.pid
fonte
Sei que essa é uma pergunta antiga, mas isso pode ajudar alguém que procura um método diferente. É isso que eu uso no Windows para matar processos que chamei.
/ IM é o nome da imagem, você também pode fazer / PID, se quiser. / T mata o processo e os processos filho. / F force termina. si, como eu o defini, é como você faz isso sem mostrar uma janela CMD. Este código é usado no python 3.
fonte
Envie o sinal para todos os processos em grupo
fonte
Eu não vi isso mencionado aqui, por isso estou colocando lá fora, caso alguém precise. Se tudo o que você deseja é garantir que seu subprocesso seja encerrado com êxito, você pode colocá-lo em um gerenciador de contexto. Por exemplo, eu queria que minha impressora padrão imprimisse uma imagem e o uso do gerenciador de contexto garantisse que o subprocesso fosse encerrado.
Eu acredito que esse método também é multiplataforma.
fonte
shell=True
, conforme a pergunta? O qual não está no seu código.thread.join()
. Espero que esteja entendido.