Uccidere il processo per nome?


99

Sto cercando di terminare un processo (in particolare iChat). Sulla riga di comando, utilizzo questi comandi:

ps -A | grep iChat 

Poi:

kill -9 PID

Tuttavia, non sono esattamente sicuro di come tradurre questi comandi in Python.

Risposte:


86

Supponendo che tu sia su una piattaforma simile a Unix (quindi ps -Aesiste),

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

ti dà ps -Al'output nella outvariabile (una stringa). Puoi suddividerlo in linee e loop su di loro ...:

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

(potresti evitare di importare signale usare al 9posto di signal.SIGKILL, ma non mi piace particolarmente quello stile, quindi preferirei usare la costante denominata in questo modo).

Ovviamente potresti eseguire elaborazioni molto più sofisticate su queste linee, ma questo imita ciò che stai facendo in shell.

Se quello che stai cercando è evitare ps, è difficile da fare su diversi sistemi Unix-like ( psè la loro API comune per ottenere un elenco di processi, in un certo senso). Ma se hai in mente uno specifico sistema simile a Unix, solo (che non richiede alcuna portabilità multipiattaforma), potrebbe essere possibile; in particolare, su Linux, lo /procpseudo-filesystem è molto utile. Ma dovrai chiarire i tuoi requisiti esatti prima che possiamo aiutarti in quest'ultima parte.


1
Ha funzionato molto bene! Utilizzo un ambiente Mac, quindi penso che sarà perfetto. Grazie per tutto il tuo aiuto.
Aaron

Sopra funziona su .nix, ma non è pitonico. Il modo appropriato, come pubblicato di seguito, è utilizzare l'approccio os.system ('taskkill / f / im exampleProcess.exe'), che fa parte del core python.
Jonesome Reinstate Monica il

@Jonesome: la tua risposta sembra essere per Windows (a causa della sintassi del comando e del nome del file .exe), ma la domanda sembra essere per Mac OS.
Vasudev Ram

Preferisco questa risposta a quella di Giampaolo Rodolà perché, anche se non è molto Pythonic, funziona su Windows ammesso che abbiate Cygwin o Msys installati. psutil non è presente in Python 2.7.10 su Windows. Il tentativo di "pip install psutil" non è riuscito sulla mia macchina, dicendo che dovevo installare Visual C ++ 9.0. Al diavolo! Preferisco di gran lunga installare Cygwin o Msys.
Andrew Bainbridge

Funziona in Windows a partire da Python 3.2, ma di solito il segnale sarà il codice di uscita del processo terminato.
Cees Timmerman

202

psutil può trovare il processo per nome e ucciderlo:

import psutil

PROCNAME = "python.exe"

for proc in psutil.process_iter():
    # check whether the process name matches
    if proc.name() == PROCNAME:
        proc.kill()

51
Questo. Perché è multipiattaforma .
Bengt

2
o se vuoi dalla riga di comando qualcosa del tipo: if "your_python_script.py" in proc.cmdline: ..kill
OWADVL

11
Lo svantaggio di questo è che richiede il psutilpacchetto, che potrebbe non essere presente sulla macchina di destinazione.
CadentOrange

1
@Bengt. Questa non è multipiattaforma se includi Windows! psutil non fa parte di Python 2.7.10. E "pip install psutil" non riesce a meno che non installi Visual C ++ 9.0, che in molti casi non sarà pratico. Comunque, congratulazioni per i tuoi 17 voti positivi :-)
Andrew Bainbridge

5
"pip install psutil" funzionerà perfettamente in quanto recupererà la versione della ruota su pypi. E no, non hai bisogno di un compilatore.
Giampaolo Rodolà

36

Se devi considerare il caso Windows per essere multipiattaforma, prova quanto segue:

os.system('taskkill /f /im exampleProcess.exe')

@ alansiqueira27 Purtroppo è solo il caso cmd di Windows. Devi vedere le risposte sopra per le soluzioni multipiattaforma.
limitcracker

Questo ha funzionato per il mio caso d'uso. Grazie! Nota che questo è pulito, uccide tutti i processi con quel nome quindi se hai più Y.exe che non terminano, tutti gli ID di processo verranno terminati.
AlgebraicGeometryStudent

23

Se hai killall:

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

O:

os.system("ps -C iChat -o pid=|xargs kill -9")

9
C'è anche pkill, anche se penso di essere l'unica persona al mondo che lo usa al posto dikillall
Michael Mrozek

1
Ok, sì, sembra che il primo comando abbia funzionato perfettamente. Grazie per l'aiuto.
Aaron

1
@MichaelMrozek Come puoi vivere con la dolce sensazione di scrivere cose come killall java?
Alois Mahdal

@ Michael che uso pkillperché l'unico di killallcui ero a conoscenza era quello "uccidi tutto".
Kyle Strand

7

questo ha funzionato per me in Windows 7

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

3

Puoi provare questo. ma prima è necessario installare psutil usandosudo pip install psutil

import psutil
for proc in psutil.process_iter(attrs=['pid', 'name']):
    if 'ichat' in proc.info['name']:
        proc.kill()

almeno questo è portatile, anche se la risposta accettata descrive già questa soluzione.
Jean-François Fabre

2

Il codice seguente ucciderà tutti i programmi orientati a 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)

1

Puoi usarlo pkill <process_name>in un sistema Unix per uccidere il processo per nome.

Quindi il codice Python sarà:

>>> import os
>>> process_name=iChat
>>> os.system('pkill '+process_name)

Tutti i sistemi che utilizzo sono Mac e quando provo a eseguire pkill mi sta solo dicendo che il comando non può essere trovato.
Aaron

1

Se vuoi terminare il processo (i) o cmd.exe che trasporta un titolo particolare.

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 ) 

Spero che sia d'aiuto. Le loro potrebbero essere numerose soluzioni migliori per il mio.


0

puoi usare il modulo WMI per farlo su Windows, anche se è molto più complicato di quello a cui sei abituato unix; import WMIrichiede molto tempo e c'è un dolore intermedio per arrivare al processo.


0

Per me l'unica cosa che ha funzionato è stata:

Per esempio

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

0

9 rappresenta il segnale SIGKILL. Quindi puoi usare KILLal posto di 9

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

0r

os.sytem("kill -KILL 1234")

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)

0

La risposta di Alex Martelli non funzionerà in Python 3 perché outsarà un oggetto byte e quindi risulterà in un TypeError: a bytes-like object is required, not 'str'test if 'iChat' in line:.

Citando dalla documentazione del sottoprocesso :

communic () restituisce una tupla (stdout_data, stderr_data). I dati saranno stringhe se i flussi sono stati aperti in modalità testo; in caso contrario, byte.

Per Python 3, questo viene risolto aggiungendo text=True(> = Python 3.7) o l' universal_newlines=Trueargomento al Popencostruttore. outverrà quindi restituito come oggetto stringa.

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)

In alternativa, puoi creare una stringa utilizzando il metodo decode () dei byte.

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)

-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()
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.