Tuer le processus par son nom?

100

J'essaye de tuer un processus (en particulier iChat). Sur la ligne de commande, j'utilise ces commandes:

ps -A | grep iChat 

Ensuite:

kill -9 PID

Cependant, je ne sais pas exactement comment traduire ces commandes en Python.

Aaron
la source

Réponses:

86

En supposant que vous êtes sur une plate-forme de type Unix (donc qui ps -Aexiste),

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

vous donne ps -Ala sortie de la outvariable (une chaîne). Vous pouvez le décomposer en lignes et faire une boucle dessus ...:

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

(vous pouvez éviter d'importer signalet utiliser à la 9place de signal.SIGKILL, mais je n'aime pas particulièrement ce style, donc je préfère utiliser la constante nommée de cette façon).

Bien sûr, vous pourriez faire un traitement beaucoup plus sophistiqué sur ces lignes, mais cela imite ce que vous faites en shell.

Si ce que vous recherchez est d'éviter ps, c'est difficile à faire sur différents systèmes de type Unix ( psest leur API commune pour obtenir une liste de processus, dans un sens). Mais si vous avez en tête un système spécifique de type Unix uniquement (ne nécessitant aucune portabilité multiplateforme), cela peut être possible; en particulier, sous Linux, le /procpseudo-système de fichiers est très utile. Mais vous devrez clarifier vos exigences exactes avant que nous puissions vous aider sur cette dernière partie.

Alex Martelli
la source
1
Cela a très bien fonctionné! J'utilise un environnement Mac donc je pense que ce sera parfait. Je vous remercie pour votre aide.
Aaron
Ci-dessus fonctionne sur .nix, mais n'est pas pythonique. La manière appropriée, comme indiqué ci-dessous, est d'utiliser l'approche os.system ('taskkill / f / im exampleProcess.exe'), qui fait partie du noyau python.
Jonesome réintègre Monica le
@Jonesome: Votre réponse semble être pour Windows (en raison de la syntaxe de la commande et du nom de fichier .exe), mais la question semble être pour Mac OS.
Vasudev Ram
Je préfère cette réponse à celle de Giampaolo Rodolà car, même si ce n'est pas très pythonique, cela fonctionne sous Windows en supposant que Cygwin ou Msys soit installé. psutil n'est pas présent dans Python 2.7.10 sous Windows. La tentative de "pip install psutil" a échoué sur ma machine, disant que je devais installer Visual C ++ 9.0. Vissez ça! Je préfère de loin installer Cygwin ou Msys.
Andrew Bainbridge le
Fonctionne sous Windows depuis Python 3.2, mais le signal sera généralement le code de sortie du processus tué.
Cees Timmerman
206

psutil peut trouver le processus par son nom et le tuer:

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à
la source
52
Ce. Parce que c'est multiplateforme .
Bengt
2
ou si vous voulez par ligne de commande quelque chose comme: if "your_python_script.py" dans proc.cmdline: ..kill
OWADVL
11
L'inconvénient est que cela nécessite le psutilpackage, qui peut ne pas être présent sur la machine cible.
CadentOrange
1
@Bengt. Ce n'est pas multiplateforme si vous incluez Windows! psutil ne fait pas partie de Python 2.7.10. Et «pip install psutil» échoue à moins que vous n'installiez Visual C ++ 9.0, ce qui ne sera pas pratique dans de nombreux cas. Encore, félicitations pour vos 17 votes positifs :-)
Andrew Bainbridge
5
"pip install psutil" fonctionnera très bien car il récupérera la version de la roue sur pypi. Et non, vous n'avez pas besoin d'un compilateur.
Giampaolo Rodolà
36

Si vous devez considérer le cas Windows pour être multiplateforme, essayez ce qui suit:

os.system('taskkill /f /im exampleProcess.exe')
limitcracker
la source
@ alansiqueira27 Malheureusement, ce n'est que le cas Windows cmd. Vous devez voir les réponses ci-dessus pour les solutions multiplateformes.
limitcracker
Cela a fonctionné pour mon cas d'utilisation. Merci! Notez que c'est bien, cela tue tous les processus de ce nom, donc si vous avez plusieurs Y.exe qui ne se terminent pas, tous les identifiants de processus seront arrêtés.
AlgebraicGeometryStudent
23

Si vous avez killall:

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

Ou:

os.system("ps -C iChat -o pid=|xargs kill -9")
Matthew Flaschen
la source
9
Il y a aussi pkill, même si je pense que je suis la seule personne au monde à l'utiliser à la place dekillall
Michael Mrozek
1
Ok cool, oui, il semble que la première commande a fonctionné parfaitement. Merci pour l'aide.
Aaron
1
@MichaelMrozek Comment pouvez-vous vivre avec la douce sensation de taper des choses comme killall java?
Alois Mahdal
@Michael que j'utilise pkillparce que le seul dont killallj'étais au courant était celui "tuer tout".
Kyle Strand
7

cela a fonctionné pour moi dans windows 7

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

Vous pouvez essayer ceci. mais avant de devoir installer psutil en utilisantsudo pip install psutil

import psutil
for proc in psutil.process_iter(attrs=['pid', 'name']):
    if 'ichat' in proc.info['name']:
        proc.kill()
Bakarali Sunasra
la source
au moins c'est portable, même si la réponse acceptée décrit déjà cette solution.
Jean-François Fabre
2

Le code ci-dessous supprimera tous les programmes orientés 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
la source
1

Vous pouvez utiliser pkill <process_name> dans un système unix pour tuer le processus par son nom.

Ensuite, le code python sera:

>>> import os
>>> process_name=iChat
>>> os.system('pkill '+process_name)
xaph
la source
Tous les systèmes que j'utilise sont Mac et lorsque j'essaie d'exécuter pkill, cela me dit simplement que la commande est introuvable.
Aaron
1

Si vous voulez tuer le (s) processus (s) ou cmd.exe portant un (des) titre (s) particulier (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 ) 

J'espère que ça aide. Leur pourrait être de nombreuses meilleures solutions à la mienne.

Thangasivam Gandhi
la source
0

vous pouvez utiliser le module WMI pour faire cela sur Windows, bien que ce soit beaucoup plus compliqué que ce à quoi vous êtes habitués à Unix; import WMIprend beaucoup de temps et il y a une douleur intermédiaire pour arriver au processus.

amwinter
la source
0

Pour moi, la seule chose qui a fonctionné est:

Par exemple

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

9 représente le signal SIGKILL. Vous pouvez donc utiliser KILLà la place de 9

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

0r

os.sytem("kill -KILL 1234")
SuperNova
la source
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
la source
0

La réponse Alex Martelli ne fonctionnera pas dans Python 3 car outsera un objet octets et entraînera donc un TypeError: a bytes-like object is required, not 'str'lors du testif 'iChat' in line: .

Citations de la documentation des sous-processus :

communique () renvoie un tuple (stdout_data, stderr_data). Les données seront des chaînes si les flux ont été ouverts en mode texte; sinon, octets.

Pour Python 3, ceci est résolu en ajoutant le text=True(> = Python 3.7) ou l' universal_newlines=Trueargument au Popenconstructeur. outsera alors renvoyé sous forme d'objet chaîne.

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)

Vous pouvez également créer une chaîne en utilisant la méthode decode () d'octets.

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
la source
-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
la source