Prozess mit Namen töten?

99

Ich versuche, einen Prozess (speziell iChat) zu beenden. In der Befehlszeile verwende ich folgende Befehle:

ps -A | grep iChat 

Dann:

kill -9 PID

Ich bin mir jedoch nicht ganz sicher, wie ich diese Befehle in Python übersetzen soll.

Aaron
quelle

Antworten:

86

Angenommen, Sie befinden sich auf einer Unix-ähnlichen Plattform (so dass diese ps -Aexistiert),

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

gibt Ihnen ps -Adie Ausgabe in der outVariablen (eine Zeichenfolge). Sie können es in Zeilen zerlegen und auf ihnen schleifen ...:

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

(Sie könnten das Importieren vermeiden signalund 9stattdessen verwenden signal.SIGKILL, aber ich mag diesen Stil einfach nicht besonders, deshalb würde ich die benannte Konstante lieber auf diese Weise verwenden).

Natürlich könnten Sie diese Zeilen viel ausgefeilter verarbeiten, aber dies ahmt nach, was Sie in der Shell tun.

Wenn Sie vermeiden psmöchten, ist dies auf verschiedenen Unix-ähnlichen Systemen schwierig ( psin gewissem Sinne die gemeinsame API zum Abrufen einer Prozessliste). Wenn Sie jedoch nur an ein bestimmtes Unix-ähnliches System denken (das keine plattformübergreifende Portabilität erfordert), ist dies möglicherweise möglich. Insbesondere unter Linux ist das /procPseudo-Dateisystem sehr hilfreich. Sie müssen jedoch Ihre genauen Anforderungen klären, bevor wir in diesem letzten Teil helfen können.

Alex Martelli
quelle
1
Das hat sehr gut funktioniert! Ich verwende eine Mac-Umgebung und denke, dass dies perfekt sein wird. Danke für all deine Hilfe.
Aaron
Oben funktioniert auf .nix, ist aber nicht pythonisch. Wie unten angegeben, können Sie den Ansatz os.system ('taskkill / f / im exampleProcess.exe') verwenden, der Teil von Core Python ist.
Jonesome Reinstate Monica
@Jonesome: Ihre Antwort scheint für Windows zu sein (aufgrund der Befehlssyntax und des Dateinamens .exe), aber die Frage scheint für Mac OS zu sein.
Vasudev Ram
Ich bevorzuge diese Antwort gegenüber der von Giampaolo Rodolà, da sie, obwohl sie nicht sehr pythonisch ist, unter Windows funktioniert, vorausgesetzt, Sie haben Cygwin oder Msys installiert. psutil ist in Python 2.7.10 unter Windows nicht vorhanden. Der Versuch, "pip install psutil" auszuführen, ist auf meinem Computer fehlgeschlagen. Ich musste Visual C ++ 9.0 installieren. Scheiß drauf! Ich würde viel lieber Cygwin oder Msys installieren.
Andrew Bainbridge
Funktioniert unter Windows seit Python 3.2, aber normalerweise ist das Signal der Exit-Code des abgebrochenen Prozesses.
Cees Timmerman
201

psutil kann den Prozess anhand seines Namens finden und töten:

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à
quelle
51
Dies. Weil es plattformübergreifend ist .
Bengt
2
oder wenn Sie über die Befehlszeile etwas wollen wie: wenn "your_python_script.py" in proc.cmdline: ..kill
OWADVL
11
Der Nachteil dabei ist, dass das psutilPaket erforderlich ist , das möglicherweise nicht auf dem Zielcomputer vorhanden ist.
CadentOrange
1
@ Bengt. Dies ist nicht plattformübergreifend, wenn Sie Windows einschließen! psutil ist nicht Teil von Python 2.7.10. Und "pip install psutil" schlägt fehl, es sei denn, Sie installieren Visual C ++ 9.0, was in vielen Fällen unpraktisch ist. Trotzdem herzlichen Glückwunsch zu Ihren 17 Upvotes :-)
Andrew Bainbridge
5
"pip install psutil" funktioniert einwandfrei, da die Radversion auf pypi abgerufen wird. Und nein, Sie brauchen keinen Compiler.
Giampaolo Rodolà
36

Wenn Sie den Windows-Fall berücksichtigen müssen, um plattformübergreifend zu sein, versuchen Sie Folgendes:

os.system('taskkill /f /im exampleProcess.exe')
Limitcracker
quelle
@ alansiqueira27 Leider ist es nur der Windows-Cmd-Fall. Sie müssen die obigen Antworten für plattformübergreifende Lösungen sehen.
Limitcracker
Dies funktionierte für meinen Anwendungsfall. Danke! Beachten Sie, dass dies ordentlich ist und alle Prozesse mit diesem Namen beendet. Wenn also mehrere Y.exe nicht beendet werden, werden alle Prozess-IDs davon beendet.
AbstractAlgebraLearner
23

Wenn Sie Killall haben:

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

Oder:

os.system("ps -C iChat -o pid=|xargs kill -9")
Matthew Flaschen
quelle
9
Es gibt auch pkill, obwohl ich denke, ich bin die einzige Person auf der Welt, die es anstelle vonkillall
Michael Mrozek
1
Ok cool, ja, es sieht so aus, als ob der erste Befehl perfekt funktioniert hat. Danke für die Hilfe.
Aaron
1
@MichaelMrozek Wie kannst du mit dem süßen Gefühl leben, Dinge wie zu tippen killall java?
Alois Mahdal
@ Michael Ich benutze, pkillweil das einzige, was killallmir bewusst war, das "alles töten" war.
Kyle Strand
7

Das hat bei mir in Windows 7 funktioniert

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

Sie können dies versuchen. aber bevor Sie psutil mit installieren müssensudo pip install psutil

import psutil
for proc in psutil.process_iter(attrs=['pid', 'name']):
    if 'ichat' in proc.info['name']:
        proc.kill()
Bakarali Sunasra
quelle
Zumindest ist dies portabel, auch wenn die akzeptierte Antwort diese Lösung bereits beschreibt.
Jean-François Fabre
2

Der folgende Code beendet alle iChat-orientierten Programme:

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
quelle
1

Sie können pkill <process_name>in einem Unix-System verwenden, um den Prozess nach Namen zu beenden.

Dann lautet der Python-Code:

>>> import os
>>> process_name=iChat
>>> os.system('pkill '+process_name)
xaph
quelle
Alle Systeme, die ich verwende, sind Macs. Wenn ich versuche, pkill auszuführen, wird mir nur mitgeteilt, dass der Befehl nicht gefunden werden kann.
Aaron
1

Wenn Sie die Prozesse oder cmd.exe mit einem bestimmten Titel beenden möchten.

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 ) 

Ich hoffe es hilft. Es könnten zahlreiche bessere Lösungen für meine sein.

Thangasivam Gandhi
quelle
0

Sie können das WMI-Modul verwenden, um dies unter Windows zu tun, obwohl es viel umständlicher ist, als Sie es von Unix-Leuten gewohnt sind. import WMIEs dauert lange und es gibt mittlere Schmerzen, um den Prozess zu bekommen.

amwinter
quelle
0

Für mich hat nur Folgendes funktioniert:

Beispielsweise

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

9 repräsentiert das SIGKILL-Signal. Sie können also KILLanstelle von 9 verwenden

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

0r

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

Die Antwort von Alex Martelli funktioniert in Python 3 nicht, da outsie ein Byte-Objekt ist und daher TypeError: a bytes-like object is required, not 'str'beim Testen zu einem führt if 'iChat' in line:.

Zitieren aus Teilprozess Dokumentation :

communic () gibt ein Tupel zurück (stdout_data, stderr_data). Die Daten sind Zeichenfolgen, wenn Streams im Textmodus geöffnet wurden. ansonsten Bytes.

Für Python 3 wird dies gelöst, indem dem Konstruktor das Argument text=True(> = Python 3.7) oder hinzugefügt wird . wird dann als String-Objekt zurückgegeben.universal_newlines=TruePopenout

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)

Alternativ können Sie eine Zeichenfolge mit der Methode decode () von Bytes erstellen.

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
quelle
-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
quelle