Zabić proces według nazwy?

100

Próbuję zabić proces (szczególnie iChat). W wierszu poleceń używam tych poleceń:

ps -A | grep iChat 

Następnie:

kill -9 PID

Jednak nie jestem do końca pewien, jak przetłumaczyć te polecenia na Python.

Aaron
źródło

Odpowiedzi:

86

Zakładając, że jesteś na platformie podobnej do Uniksa (więc taka ps -Aistnieje),

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

daje ps -Awynik w outzmiennej (łańcuch). Możesz podzielić to na linie i zapętlić na nich ...:

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

(możesz uniknąć importowania signali używać 9zamiast niego signal.SIGKILL, ale po prostu nie lubię tego stylu, więc wolałbym użyć nazwanej stałej w ten sposób).

Oczywiście na tych liniach można by wykonać znacznie bardziej wyrafinowane przetwarzanie, ale to naśladuje to, co robisz w powłoce.

Jeśli tym, czego szukasz, jest unikanie ps, trudno to zrobić w różnych systemach uniksopodobnych ( psw pewnym sensie jest to ich wspólny interfejs API do uzyskania listy procesów). Ale jeśli masz na myśli tylko konkretny system podobny do Uniksa (nie wymagającego przenoszenia między platformami), może to być możliwe; w szczególności w systemie Linux/proc pseudosystem plików jest bardzo pomocny. Ale zanim będziemy mogli pomóc w tej drugiej części, musisz wyjaśnić swoje dokładne wymagania.

Alex Martelli
źródło
1
To działało bardzo dobrze! Używam środowiska Mac, więc myślę, że będzie to idealne. Dziękuję Ci za całą twoją pomoc.
Aaron
Powyższe działa na .nix, ale nie jest pythonowe. Sposób, jak opisano poniżej, polega na zastosowaniu podejścia os.system („taskkill / f / im exampleProcess.exe”), które jest częścią podstawowego języka Python.
Jonesome Przywróć Monikę
@Jonesome: Twoja odpowiedź wydaje się dotyczyć systemu Windows (ze względu na składnię poleceń i nazwę pliku .exe), ale pytanie wydaje się dotyczyć systemu Mac OS.
Vasudev Ram
Wolę tę odpowiedź od Giampaolo Rodolà, ponieważ chociaż nie jest to bardzo Pythonic, działa w systemie Windows, zakładając, że masz zainstalowany Cygwin lub Msys. psutil nie występuje w Pythonie 2.7.10 w systemie Windows. Próba „pip install psutil” nie powiodła się na moim komputerze, mówiąc, że muszę zainstalować Visual C ++ 9.0. Chrzanić to! Wolę zainstalować Cygwin lub Msys.
Andrew Bainbridge
Działa w systemie Windows od wersji Python 3.2, ale zazwyczaj sygnał będzie kodem zakończenia zabitego procesu.
Cees Timmerman,
206

psutil może znaleźć proces według nazwy i zabić go:

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à
źródło
52
To. Ponieważ jest to platforma wieloplatformowa .
Bengt,
2
lub jeśli chcesz, używając wiersza poleceń, na przykład: if "your_python_script.py" w proc.cmdline: ..kill
OWADVL
11
Wadą tego jest to, że wymaga psutilpakietu, którego może nie być na maszynie docelowej.
CadentOrange
1
@Bengt. Nie jest to platforma wieloplatformowa, jeśli zawiera system Windows! psutil nie jest częścią Pythona 2.7.10. A „pip install psutil” kończy się niepowodzeniem, chyba że zainstalujesz Visual C ++ 9.0, co w wielu przypadkach będzie niepraktyczne. Mimo to gratulujemy 17 głosów pozytywnych :-)
Andrew Bainbridge
5
"pip install psutil" będzie działał dobrze, ponieważ pobierze wersję koła na pypi. I nie, nie potrzebujesz kompilatora.
Giampaolo Rodolà
36

Jeśli musisz wziąć pod uwagę przypadek systemu Windows, aby działać na wielu platformach, wypróbuj następujące rozwiązania:

os.system('taskkill /f /im exampleProcess.exe')
limitcracker
źródło
@ alansiqueira27 Niestety jest to tylko przypadek cmd systemu Windows. Musisz zobaczyć powyższe odpowiedzi dla rozwiązań wieloplatformowych.
limitcracker
To zadziałało w moim przypadku użycia. Dzięki! Zauważ, że jest to fajne, zabija wszystkie procesy o tej nazwie, więc jeśli masz wiele plików Y.exe, które się nie kończą, wszystkie identyfikatory procesów zostaną zakończone.
AlgebraicGeometryStudent
23

Jeśli masz killall:

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

Lub:

os.system("ps -C iChat -o pid=|xargs kill -9")
Matthew Flaschen
źródło
9
Jest też pkill, choć myślę, że jestem jedyną osobą na świecie, która go używa zamiastkillall
Michał Mrozek
1
Ok, fajnie, tak, wygląda na to, że pierwsze polecenie działało idealnie. Dzięki za pomoc.
Aaron
1
@MichaelMrozek Jak możesz żyć ze słodkim uczuciem pisania na klawiaturze killall java?
Alois Mahdal
@Michael, którego używam, pkillponieważ jedyne, o killallczym wiedziałem, to „zabij wszystko”.
Kyle Strand
7

to działało dla mnie w systemie Windows 7

import subprocess
subprocess.call("taskkill /IM geckodriver.exe")
d0dulk0
źródło
3

Możesz tego spróbować. ale zanim będziesz musiał zainstalować psutil używającsudo pip install psutil

import psutil
for proc in psutil.process_iter(attrs=['pid', 'name']):
    if 'ichat' in proc.info['name']:
        proc.kill()
Bakarali Sunasra
źródło
przynajmniej jest to przenośne, nawet jeśli zaakceptowana odpowiedź już opisuje to rozwiązanie.
Jean-François Fabre
2

Poniższy kod zabije wszystkie programy zorientowane na 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
źródło
1

Możesz użyć pkill <process_name> w systemie uniksowym do zabicia procesu według nazwy.

Wtedy kod Pythona będzie wyglądał następująco:

>>> import os
>>> process_name=iChat
>>> os.system('pkill '+process_name)
xaph
źródło
Wszystkie systemy, których używam, to komputery Mac, a kiedy próbuję uruchomić pkill, po prostu mówi mi, że nie można znaleźć polecenia.
Aaron
1

Jeśli chcesz zabić proces (y) lub cmd.exe niosący określone tytuły.

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 ) 

Mam nadzieję, że to pomoże. Mógłbym mieć wiele lepszych rozwiązań.

Thangasivam Gandhi
źródło
0

możesz użyć modułu WMI, aby to zrobić w systemie Windows, chociaż jest o wiele bardziej skomplikowany niż przyzwyczajeni do tego użytkownicy uniksowi; import WMIzajmuje dużo czasu, a proces ten wymaga pośredniego bólu.

zimą
źródło
0

Dla mnie jedyne, co zadziałało, to:

Na przykład

import subprocess
proc = subprocess.Popen(["pkill", "-f", "scriptName.py"], stdout=subprocess.PIPE)
proc.wait()
Marco Mac
źródło
0

9 oznacza sygnał SIGKILL. Możesz więc użyć KILLzamiast 9

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

0r

os.sytem("kill -KILL 1234")
SuperNova
źródło
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
źródło
0

Odpowiedź Alex Martelli nie będzie działać w Pythonie 3, ponieważ outbędzie obiektem bajtów, a zatem TypeError: a bytes-like object is required, not 'str'podczas testowania spowodujeif 'iChat' in line: .

Cytowanie z dokumentacji podprocesu :

komunikacja () zwraca krotkę (stdout_data, stderr_data). Dane będą ciągami, jeśli strumienie zostały otwarte w trybie tekstowym; w przeciwnym razie bajty.

W przypadku Pythona 3 można to rozwiązać, dodając argument text=True(> = Python 3.7) lub universal_newlines=Truedo Popenkonstruktora. outzostanie zwrócona jako obiekt typu 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)

Alternatywnie możesz utworzyć ciąg przy użyciu metody decode () bajtów.

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
źródło
-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
źródło