Убить процесс по имени?

100

Я пытаюсь убить процесс (а именно iChat). В командной строке я использую следующие команды:

ps -A | grep iChat 

Затем:

kill -9 PID

Однако я не совсем уверен, как перевести эти команды на Python.

Аарон
источник

Ответы:

86

Предполагая, что вы используете Unix-подобную платформу (так что она ps -Aсуществует),

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

дает вам ps -Aрезультат в outпеременной (строку). Вы можете разбить его на строки и зациклить на них ...:

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

(вы можете избежать импорта signalи использовать 9вместо него signal.SIGKILL, но мне просто не особенно нравится этот стиль, поэтому я бы предпочел использовать именованную константу таким образом).

Конечно, в этих строках можно было бы выполнять гораздо более сложную обработку, но это имитирует то, что вы делаете в оболочке.

Если вы избегаете того ps, чего хотите , то это трудно сделать в разных Unix-подобных системах ( psв некотором смысле это их общий API для получения списка процессов). Но если вы имеете в виду только конкретную Unix-подобную систему (не требующую кроссплатформенной переносимости), это может быть возможным; в частности, в Linux /procочень полезна псевдофайловая система. Но вам нужно будет уточнить ваши точные требования, прежде чем мы сможем помочь в этой последней части.

Алекс Мартелли
источник
1
Это сработало очень хорошо! Я использую среду Mac, поэтому думаю, что это будет идеально. Спасибо тебе за помощь.
Аарон
Выше работает с .nix, но не питоническим. Подходящий способ, как указано ниже, заключается в использовании подхода os.system ('taskkill / f / im exampleProcess.exe'), который является частью ядра Python.
Jonesome Reinstate Monica
@Jonesome: Ваш ответ, похоже, относится к Windows (из-за синтаксиса команды и имени файла .exe), но вопрос, похоже, относится к Mac OS.
Vasudev Ram
Я предпочитаю этот ответ Джампаоло Родола, потому что, хотя он не очень Pythonic, он работает в Windows, если у вас установлен Cygwin или Msys. psutil отсутствует в Python 2.7.10 в Windows. Попытка «pip install psutil» не удалась на моей машине, сказав, что мне нужно установить Visual C ++ 9.0. Да пошло оно! Я бы предпочел установить Cygwin или Msys.
Эндрю Бейнбридж
Работает в Windows, начиная с Python 3.2, но обычно сигналом будет код выхода убитого процесса.
Cees Timmerman
206

psutil может найти процесс по имени и убить его:

import psutil

PROCNAME = "python.exe"

for proc in psutil.process_iter():
    # check whether the process name matches
    if proc.name() == PROCNAME:
        proc.kill()
Джампаоло Родола
источник
52
Это. Потому что это кроссплатформенный .
Bengt
2
или если вы хотите в командной строке что-то вроде: if "your_python_script.py" в proc.cmdline: ..kill
OWADVL
11
Обратной стороной является то, что для этого требуется psutilпакет, который может отсутствовать на целевой машине.
CadentOrange 05
1
@Bengt. Это не кроссплатформенность, если вы включаете Windows! psutil не является частью Python 2.7.10. И "pip install psutil" завершится ошибкой, если вы не установите Visual C ++ 9.0, что во многих случаях будет непрактично. Тем не менее, поздравляю с вашими 17 голосами :-)
Эндрю Бейнбридж
5
"pip install psutil" будет работать нормально, поскольку он получит версию wheel на pypi. И нет, вам не нужен компилятор.
Джампаоло Родола 05
36

Если вам нужно рассмотреть случай Windows, чтобы быть кроссплатформенным, попробуйте следующее:

os.system('taskkill /f /im exampleProcess.exe')
ограничитель
источник
@ alansiqueira27 К сожалению, дело только в Windows cmd. Вы должны увидеть ответы на кросс-платформенные решения.
limitcracker 01
Это сработало для моего варианта использования. Спасибо! Обратите внимание, что это аккуратно, он убивает все процессы с этим именем, поэтому, если у вас есть несколько не завершающихся Y.exe, все идентификаторы процесса будут завершены.
AlgebraicGeometryStudent
23

Если у вас есть killall:

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

Или:

os.system("ps -C iChat -o pid=|xargs kill -9")
Мэтью Флашен
источник
9
Есть также pkill, хотя я думаю, что я единственный человек в мире, который использует его вместоkillall
Майкл Мрозек
1
Хорошо, круто, да, похоже, первая команда сработала идеально. Спасибо за помощь.
Аарон
1
@MichaelMrozek Как вы можете жить с приятным чувством печатать такие вещи, как killall java?
Алоис Махдал
@Michael Я использую, pkillпотому что единственное, о чем killallя знал, это "убить все".
Kyle Strand
7

это сработало для меня в Windows 7

import subprocess
subprocess.call("taskkill /IM geckodriver.exe")
d0dulk0
источник
3

Вы можете попробовать это. но перед установкой psutil с помощьюsudo pip install psutil

import psutil
for proc in psutil.process_iter(attrs=['pid', 'name']):
    if 'ichat' in proc.info['name']:
        proc.kill()
Бакарали Сунасра
источник
по крайней мере, это переносимо, даже если принятый ответ уже описывает это решение.
Жан-Франсуа Фабр
2

Приведенный ниже код уничтожит все программы, ориентированные на 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

Ты можешь использовать pkill <process_name> в системе unix, чтобы убить процесс по имени.

Тогда код python будет:

>>> import os
>>> process_name=iChat
>>> os.system('pkill '+process_name)
ксаф
источник
Все системы, которые я использую, - это Mac, и когда я пытаюсь запустить pkill, он просто сообщает мне, что команда не может быть найдена.
Аарон
1

Если вы хотите убить процесс (ы) или cmd.exe с определенным заголовком (ами).

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 ) 

Надеюсь, поможет. Их может быть множество лучших решений для моей.

Тангасивам Ганди
источник
0

вы можете использовать модуль WMI, чтобы сделать это в Windows, хотя это гораздо более неудобно, чем привыкли пользователи Unix; import WMIзанимает много времени и есть промежуточная боль, чтобы добраться до этого процесса.

amwinter
источник
0

Для меня единственное, что сработало, это:

Например

import subprocess
proc = subprocess.Popen(["pkill", "-f", "scriptName.py"], stdout=subprocess.PIPE)
proc.wait()
Марко Мак
источник
0

9 представляет сигнал SIGKILL. Таким образом, вы можете использовать KILLвместо 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

Ответ Алекса Мартелли не будет работать в Python 3, потому что outон будет байтовым объектом и, таким образом, приведет к ошибке TypeError: a bytes-like object is required, not 'str'при тестированииif 'iChat' in line: .

Цитата из документации подпроцесса :

communication () возвращает кортеж (stdout_data, stderr_data). Данные будут строками, если потоки открывались в текстовом режиме; в противном случае байты.

Для Python 3 это решается путем добавления аргумента text=True(> = Python 3.7) или universal_newlines=Trueв Popenконструктор. outзатем будет возвращен как строковый объект.

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)

В качестве альтернативы вы можете создать строку, используя метод байтов decode ().

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()
Петерик
источник