Matar o processo pelo nome?

99

Estou tentando encerrar um processo (especificamente o iChat). Na linha de comando, uso estes comandos:

ps -A | grep iChat 

Então:

kill -9 PID

No entanto, não tenho certeza de como traduzir esses comandos para Python.

Aaron
fonte

Respostas:

86

Supondo que você esteja em uma plataforma semelhante ao Unix (para que ps -Aexista),

>>> import subprocess, signal
>>> import os
>>> p = subprocess.Popen(['ps', '-A'], stdout=subprocess.PIPE)
>>> out, err = p.communicate()

fornece ps -Aa saída na outvariável (uma string). Você pode dividi-lo em linhas e fazer um loop nelas ...:

>>> for line in out.splitlines():
...   if 'iChat' in line:
...     pid = int(line.split(None, 1)[0])
...     os.kill(pid, signal.SIGKILL)
... 

(você poderia evitar a importação signale usar em 9vez de signal.SIGKILL, mas eu simplesmente não gosto desse estilo, então prefiro usar a constante nomeada desta forma).

Claro que você poderia fazer um processamento muito mais sofisticado nessas linhas, mas isso imita o que você está fazendo no shell.

Se o que você está procurando é evitar ps, isso é difícil de fazer em diferentes sistemas semelhantes ao Unix ( psé a API comum deles para obter uma lista de processos, em certo sentido). Mas se você tiver um sistema semelhante ao Unix específico em mente, apenas (não requer qualquer portabilidade de plataforma cruzada), pode ser possível; em particular, no Linux, o /procpseudo-sistema de arquivos é muito útil. Mas você precisará esclarecer seus requisitos exatos antes de podermos ajudar nesta última parte.

Alex Martelli
fonte
1
Funcionou muito bem! Estou executando um ambiente Mac, então acho que isso será perfeito. Obrigado por toda sua ajuda.
Aaron
Acima funciona em .nix, mas não é pythônico. A maneira apropriada, conforme postado abaixo, é usar a abordagem os.system ('taskkill / f / im exampleProcess.exe'), que faz parte do núcleo do Python.
Jonesome Reintegrar Monica em
@Jonesome: Sua resposta parece ser para o Windows (devido à sintaxe do comando e o nome do arquivo .exe), mas a pergunta parece ser para o Mac OS.
Vasudev Ram
Prefiro esta resposta a de Giampaolo Rodolà porque, embora não seja muito Pythônico, funciona no Windows assumindo que você tem Cygwin ou Msys instalado. psutil não está presente no Python 2.7.10 no Windows. A tentativa de "pip install psutil" falhou em minha máquina, dizendo que eu precisava instalar o Visual C ++ 9.0. Dane-se isso! Prefiro instalar o Cygwin ou o Msys.
Andrew Bainbridge
Funciona no Windows desde o Python 3.2, mas normalmente o sinal será o código de saída do processo eliminado.
Cees Timmerman
202

psutil pode encontrar o processo pelo nome e eliminá- lo:

import psutil

PROCNAME = "python.exe"

for proc in psutil.process_iter():
    # check whether the process name matches
    if proc.name() == PROCNAME:
        proc.kill()
Giampaolo Rodolà
fonte
51
Este. Porque é plataforma cruzada .
Bengt
2
ou se você quiser por linha de comando algo como: if "your_python_script.py" em proc.cmdline: ..kill
OWADVL
11
A desvantagem disso é que requer o psutilpacote, que pode não estar presente na máquina de destino.
CadentOrange
1
@Bengt. Isso não é multiplataforma se você incluir o Windows! psutil não faz parte do Python 2.7.10. E "pip install psutil" falhará a menos que você instale o Visual C ++ 9.0, o que será impraticável em muitos casos. Ainda assim, parabéns pelos seus 17 votos positivos :-)
Andrew Bainbridge
5
"pip install psutil" funcionará perfeitamente, pois recuperará a versão do wheel no pypi. E não, você não precisa de um compilador.
Giampaolo Rodolà,
36

Se você tiver que considerar o caso do Windows para ser multiplataforma, tente o seguinte:

os.system('taskkill /f /im exampleProcess.exe')
quebrador de limites
fonte
@ alansiqueira27 Infelizmente é apenas o caso cmd do Windows. Você tem que ver as respostas acima para soluções de plataforma cruzada.
limitcracker 01 de
Isso funcionou para meu caso de uso. Obrigado! Observe que isso é legal, ele mata todos os processos com esse nome, portanto, se você tiver vários Y.exe não encerrados, todos os IDs de processo dele serão encerrados.
AlgebraicGeometryStudent
23

Se você tiver killall:

os.system("killall -9 iChat");

Ou:

os.system("ps -C iChat -o pid=|xargs kill -9")
Matthew Flaschen
fonte
9
Há também pkill, embora eu pense que sou a única pessoa no mundo que usa isso em vez dekillall
Michael Mrozek
1
Ok, legal, sim, parece que o primeiro comando funcionou perfeitamente. Obrigado pela ajuda.
Aaron
1
@MichaelMrozek Como você pode viver com a doce sensação de digitar coisas como killall java?
Alois Mahdal,
@Michael eu uso pkillporque o único que killalleu conhecia era o "mata tudo".
Kyle Strand
7

Isso funcionou para mim no Windows 7

import subprocess
subprocess.call("taskkill /IM geckodriver.exe")
d0dulk0
fonte
3

Você pode tentar isso. mas antes você precisa instalar o psutil usandosudo pip install psutil

import psutil
for proc in psutil.process_iter(attrs=['pid', 'name']):
    if 'ichat' in proc.info['name']:
        proc.kill()
Bakarali Sunasra
fonte
pelo menos isso é portátil, mesmo que a resposta aceita já descreva essa solução.
Jean-François Fabre
2

O código a seguir eliminará todos os programas orientados para iChat:

p = subprocess.Popen(['pgrep', '-l' , 'iChat'], stdout=subprocess.PIPE)
out, err = p.communicate()

for line in out.splitlines():        
    line = bytes.decode(line)
    pid = int(line.split(None, 1)[0])
    os.kill(pid, signal.SIGKILL)
Poobalan
fonte
1

Você pode usar pkill <process_name>em um sistema unix para matar processos pelo nome.

Então, o código python será:

>>> import os
>>> process_name=iChat
>>> os.system('pkill '+process_name)
xaph
fonte
Todos os sistemas que estou usando são Mac e quando tento executar o pkill é apenas me avisando que o comando não foi encontrado.
Aaron
1

Se você deseja encerrar o (s) processo (s) ou cmd.exe que carrega um determinado título (s).

import csv, os
import subprocess
# ## Find the command prompt windows.
# ## Collect the details of the command prompt windows and assign them.
tasks = csv.DictReader(subprocess.check_output('tasklist /fi "imagename eq cmd.exe" /v /fo csv').splitlines(), delimiter=',', quotechar='"')
# ## The cmds with titles to be closed.
titles= ["Ploter", "scanFolder"]

# ## Find the PIDs of the cmds with the above titles.
PIDList = []
for line in tasks:
    for title in titles:
        if  title in line['Window Title']:
           print line['Window Title']       
           PIDList.append(line['PID'])

# ## Kill the CMDs carrying the PIDs in PIDList
for id in PIDList:
    os.system('taskkill /pid ' + id ) 

Espero que ajude. Podem haver várias soluções melhores para mim.

Thangasivam Gandhi
fonte
0

você pode usar o módulo WMI para fazer isso no Windows, embora seja muito mais desajeitado do que seu pessoal do Unix está acostumado; import WMIleva muito tempo e há uma dor intermediária para chegar ao processo.

inverno
fonte
0

Para mim, a única coisa que funcionou foi:

Por exemplo

import subprocess
proc = subprocess.Popen(["pkill", "-f", "scriptName.py"], stdout=subprocess.PIPE)
proc.wait()
Marco Mac
fonte
0

9 representa o sinal SIGKILL. Então você pode usar KILLno lugar de 9

os.system("kill -s KILL 1234")

0r

os.sytem("kill -KILL 1234")
Super Nova
fonte
0
import os, signal

def check_kill_process(pstring):
    for line in os.popen("ps ax | grep " + pstring + " | grep -v grep"):
        fields = line.split()
        pid = fields[0]
        os.kill(int(pid), signal.SIGKILL)
Abhishek Kumar
fonte
0

A resposta de Alex Martelli não funcionará no Python 3 porque outserá um objeto bytes e, portanto, resultará em um TypeError: a bytes-like object is required, not 'str'teste ao if 'iChat' in line:.

Citando a documentação do subprocesso :

Communic () retorna uma tupla (stdout_data, stderr_data). Os dados serão strings se os streams forem abertos no modo de texto; caso contrário, bytes.

Para Python 3, isso é resolvido adicionando o text=True(> = Python 3.7) ou universal_newlines=Trueargumento ao Popenconstrutor. outserá então retornado como um objeto string.

import subprocess, signal
import os

p = subprocess.Popen(['ps', '-A'], stdout=subprocess.PIPE, text=True)
out, err = p.communicate()

for line in out.splitlines():
    if 'iChat' in line:
        pid = int(line.split(None, 1)[0])    
        os.kill(pid, signal.SIGKILL)

Como alternativa, você pode criar uma string usando o método decode () de bytes.

import subprocess, signal
import os

p = subprocess.Popen(['ps', '-A'], stdout=subprocess.PIPE)
out, err = p.communicate()

for line in out.splitlines():
    if 'iChat' in line.decode('utf-8'):
        pid = int(line.split(None, 1)[0])    
        os.kill(pid, signal.SIGKILL)
Jason Stoller
fonte
-1
import psutil
pid_list=psutil.get_pid_list()
print pid_list
p = psutil.Process(1052)
print p.name
for i in pid_list:
    p = psutil.Process(i)
    p_name=p.name
    print str(i)+" "+str(p.name)
    if p_name=="PerfExp.exe":
        print "*"*20+" mam ho "+"*"*20
        p.kill()
Peterik
fonte