Кросс-платформенный способ получения PID по имени процесса в python
На хосте выполняется несколько процессов с тем же именем. Что такое кросс-платформенный способ получения PID этих процессов по имени с помощью python или jython?
- Я хочу что-то вроде
pidof
, но в python. (Во всяком случае, у меня нет pidof
.)
- Я не могу разобрать
/proc
, потому что он может быть недоступен (на HP-UX).
- Я не хочу запускать
os.popen('ps')
и анализировать вывод, потому что я думаю, что он уродлив (последовательность полей может отличаться в разных ОС).
- Целевые платформы - это Solaris, HP-UX и, возможно, другие.
Ответы
Ответ 1
Вы можете использовать psutil (https://github.com/giampaolo/psutil), который работает в Windows и UNIX:
import psutil
PROCNAME = "python.exe"
for proc in psutil.process_iter():
if proc.name() == PROCNAME:
print(proc)
На моей машине он печатает:
<psutil.Process(pid=3881, name='python.exe') at 140192133873040>
EDIT 2017-04-27 - здесь представлена более продвинутая функция полезности, которая проверяет имя на имя процессов(), cmdline() и exe():
import os
import psutil
def find_procs_by_name(name):
"Return a list of processes matching 'name'."
assert name, name
ls = []
for p in psutil.process_iter():
name_, exe, cmdline = "", "", []
try:
name_ = p.name()
cmdline = p.cmdline()
exe = p.exe()
except (psutil.AccessDenied, psutil.ZombieProcess):
pass
except psutil.NoSuchProcess:
continue
if name == name_ or cmdline[0] == name or os.path.basename(exe) == name:
ls.append(name)
return ls
Ответ 2
Нет единого межплатформенного API, вам нужно будет проверить наличие ОС. Для использования на основе posix/proc. Для Windows используйте следующий код, чтобы получить список всех pid с именами процессов, отвечающих за
from win32com.client import GetObject
WMI = GetObject('winmgmts:')
processes = WMI.InstancesOf('Win32_Process')
process_list = [(p.Properties_("ProcessID").Value, p.Properties_("Name").Value) for p in processes]
Затем вы можете легко отфильтровать процессы, которые вам нужны.
Для получения дополнительной информации о доступных свойствах Win32_Process проверьте класс Win32_Process
Ответ 3
import psutil
process = filter(lambda p: p.name() == "YourProcess.exe", psutil.process_iter())
for i in process:
print i.name,i.pid
Дайте все pids "YourProcess.exe"
Ответ 4
Я не думаю, что вы сможете найти чисто портативное решение на основе python без использования /proc или утилит командной строки, по крайней мере, не в самом python. Парсинг os.system не уродлив - кто-то должен иметь дело с несколькими платформами, будь то вы или кто-то еще. Реализация его для интересующей вас ОС должна быть довольно простой, честно.
Ответ 5
Во-первых, Windows (во всех ее воплощениях) является нестандартной ОС.
Linux (и большинство проприетарных unixen) являются стандартными операционными системами, совместимыми с POSIX.
Библиотеки C отражают эту дихотомию. Python отображает библиотеки C.
Не существует "кросс-платформенного" способа сделать это. Вы должны взломать что-то с помощью ctypes для конкретной версии Windows (XP или Vista)
Ответ 6
Нет, я боюсь. Процессы уникально идентифицируются pid не по имени. Если вы действительно должны найти pid по имени, тогда вы будете использовать что-то вроде того, что предложили, но оно не будет переносимым и, вероятно, не будет работать во всех случаях.
Если вам нужно только найти pids для определенного приложения, и у вас есть контроль над этим приложением, я бы предложил изменить это приложение, чтобы сохранить его pid в файлах в каком-то месте, где ваш script может его найти.
Ответ 7
Для jython, если используется Java 5, вы можете получить идентификатор процесса Java следующим образом:
из java.lang.management import *
pid = ManagementFactory.getRuntimeMXBean(). getName()
Ответ 8
Заметка Комментарий ThorSummoner
process = [proc for proc in psutil.process_iter() if proc.name == "YourProcess.exe"].
Я пробовал его на Debian с Python 3, я думаю, что он должен быть proc.name()
вместо proc.name
.