在主机上有多个同名进程正在运行。如何使用 Python 或 Jython 以跨平台的方式获取这些进程的名称?
- 我想要像
pidof
一样的东西,但是使用Python实现。(无论如何我都没有pidof
)。 - 我不能解析
/ proc
,因为它可能不可用(在HP-UX上)。 - 我不想运行
os.popen('ps')
并解析输出,因为我认为它很丑陋(字段序列在不同的操作系统中可能会有所不同)。 - 目标平台是 Solaris,HP-UX,和其他可能的平台。
在主机上有多个同名进程正在运行。如何使用 Python 或 Jython 以跨平台的方式获取这些进程的名称?
pidof
一样的东西,但是使用Python实现。(无论如何我都没有 pidof
)。 / proc
,因为它可能不可用(在HP-UX上)。 os.popen('ps')
并解析输出,因为我认为它很丑陋(字段序列在不同的操作系统中可能会有所不同)。您可以使用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>
编辑于2017年4月27日 - 这是一个更高级的实用函数,它会检查进程的名称是否与name()、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(p)
return ls
没有单一的跨平台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 类。pywin32
包 http://sourceforge.net/projects/pywin32/files/pywin32/ 答案应该包括这个。 - n611x007import psutil
process = filter(lambda p: p.name() == "YourProcess.exe", psutil.process_iter())
for i in process:
print i.name,i.pid
给出所有 "YourProcess.exe" 的 pid。
process = [proc for proc in psutil.process_iter() if proc.name == "YourProcess.exe"]
。 - ThorSummoner有关ThorSummoner的评论的说明
process = [proc for proc in psutil.process_iter() if proc.name == "YourProcess.exe"].
我已经在Debian上使用Python 3尝试过了,我认为应该使用proc.name()
而不是proc.name
。
首先,Windows(在所有版本中)是一种非标准操作系统。
Linux(以及大多数专有的Unix系统)是符合POSIX标准的标准操作系统。
C库反映了这种二分法。Python反映了C库。
没有“跨平台”的方法来做到这一点。您必须使用ctypes为特定版本的Windows(XP或Vista)创建一些东西。
对于Jython,如果使用Java 5,则可以按以下方式获取Java进程ID:
from java.lang.management import ManagementFactory
pid = int(ManagementFactory.getRuntimeMXBean().getName().split("@")[0])
print(pid)
这段代码将打印出你的进程ID(在我的情况下是 23968
)
我认为你不可能在纯粹基于Python的、可移植的解决方案中找到一个不使用/proc或命令行实用程序的方法,至少在Python本身中是这样。解析os.system并不丑陋——必须有人来处理多个平台,无论是你还是其他人。对于你感兴趣的操作系统来实现它应该相当容易,老实说。
只需使用:
def get_process_by_name(name):
import re, psutil
ls = list()
for p in psutil.process_iter():
if hasattr(p, 'name'):
if re.match(".*" + name + ".*", p.name()):
ls.append(p)
return ls
很抱歉,没有这样的方法。进程是通过pid而不是名称唯一标识的。如果您确实必须按名称查找pid,则需要使用类似于您提出的解决方案,但它不具备可移植性,并且可能无法在所有情况下工作。
如果您只需查找某个应用程序的pid,并且您对该应用程序有控制权,则建议将此应用程序更改为将其pid存储在某个位置的文件中,以便您的脚本可以找到它。
sys.platform
(在我的系统上是'java1.8.0_45'
)来确定底层操作系统,那么它的一些功能现在可能已经可以使用;需要修复读取/proc的错误;其他使用C扩展API的部分可能会在Stefan的工作完成后实现。 - Jim Baker