如何使用 Python 获得 Unix 或 Linux 中程序的进程 ID?

我正在用 Python 编写一些监视脚本,并试图找到一种最干净的方法来获取给定程序名称的任何随机运行程序的进程 ID

比如

ps -ef | grep MyProgram

我可以解析它的输出,但是我认为在 python 中可能有更好的方法

153443 次浏览

如果你不限制自己的标准库,我喜欢 Psutil为此。

例如,查找所有“ python”进程:

>>> import psutil
>>> [p.info for p in psutil.process_iter(attrs=['pid', 'name']) if 'python' in p.info['name']]
[{'name': 'python3', 'pid': 21947},
{'name': 'python', 'pid': 23835}]

尝试使用 pgrep。它的输出格式更简单,因此更容易解析。

适用于视窗

一种不用下载任何模块就可以获得计算机上所有程序的 pid 的方法:

import os


pids = []
a = os.popen("tasklist").readlines()
for x in a:
try:
pids.append(int(x[29:34]))
except:
pass
for each in pids:
print(each)

如果你只想要一个程序或者所有的程序都有相同的名字,并且你想要终止这个进程或者其他什么:

import os, sys, win32api


tasklistrl = os.popen("tasklist").readlines()
tasklistr = os.popen("tasklist").read()


print(tasklistr)


def kill(process):
process_exists_forsure = False
gotpid = False
for examine in tasklistrl:
if process == examine[0:len(process)]:
process_exists_forsure = True
if process_exists_forsure:
print("That process exists.")
else:
print("That process does not exist.")
raw_input()
sys.exit()
for getpid in tasklistrl:
if process == getpid[0:len(process)]:
pid = int(getpid[29:34])
gotpid = True
try:
handle = win32api.OpenProcess(1, False, pid)
win32api.TerminateProcess(handle, 0)
win32api.CloseHandle(handle)
print("Successfully killed process %s on pid %d." % (getpid[0:len(prompt)], pid))
except win32api.error as err:
print(err)
raw_input()
sys.exit()
if not gotpid:
print("Could not get process pid.")
raw_input()
sys.exit()


raw_input()
sys.exit()


prompt = raw_input("Which process would you like to kill? ")
kill(prompt)

这只是我的进程杀死程序的粘贴,我可以使它好得多,但它是好的。

可以使用下面的代码片段来解决这个任务,[0:28]是保存名称的间隔,而[29:34]包含实际的 pid。

import os


program_pid = 0
program_name = "notepad.exe"


task_manager_lines = os.popen("tasklist").readlines()
for line in task_manager_lines:
try:
if str(line[0:28]) == program_name + (28 - len(program_name) * ' ': #so it includes the whitespaces
program_pid = int(line[29:34])
break
except:
pass


print(program_pid)

另外: Python: 如何通过进程名获得 PID?

适应以前发布的答案。

def getpid(process_name):
import os
return [item.split()[1] for item in os.popen('tasklist').read().splitlines()[4:] if process_name in item.split()]


getpid('cmd.exe')
['6560', '3244', '9024', '4828']

对于 posx (Linux,BSD,等等)。.只需要挂载/proc 目录)使用/proc 中的 OS 文件更容易

可以在 python2和 python3上工作(唯一的区别是异常树,因此是“ 除了例外”,我不喜欢它,但为了保持兼容性而保留了它。也可以创建自定义异常。)

#!/usr/bin/env python


import os
import sys




for dirname in os.listdir('/proc'):
if dirname == 'curproc':
continue


try:
with open('/proc/{}/cmdline'.format(dirname), mode='rb') as fd:
content = fd.read().decode().split('\x00')
except Exception:
continue


for i in sys.argv[1:]:
if i in content[0]:
# dirname is also the number of PID
print('{0:<12} : {1}'.format(dirname, ' '.join(content)))

示例输出(它的工作方式类似于 pgrep) :

phoemur ~/python $ ./pgrep.py bash
1487         : -bash
1779         : /bin/bash

psutil:

(可与 [sudo] pip install psutil一起安装)

import psutil


# Get current process pid
current_process_pid = psutil.Process().pid
print(current_process_pid)  # e.g 12971


# Get pids by program name
program_name = 'chrome'
process_pids = [process.pid for process in psutil.process_iter() if process.name == program_name]
print(process_pids)  # e.g [1059, 2343, ..., ..., 9645]

这是费尔南多答案的简化版。这是针对 Linux 和 Python2或3的。不需要外部库,也不运行外部进程。

import glob


def get_command_pid(command):
for path in glob.glob('/proc/*/comm'):
if open(path).read().rstrip() == command:
return path.split('/')[2]

只返回找到的第一个匹配进程,这在某些情况下效果很好。要获得多个匹配进程的 PID,只需用 yield替换 return,然后用 pids = list(get_command_pid(command))获得一个列表。

或者,作为一个单独的表达式:

其中一个过程是:

next(path.split('/')[2] for path in glob.glob('/proc/*/comm') if open(path).read().rstrip() == command)

对于多个进程:

[path.split('/')[2] for path in glob.glob('/proc/*/comm') if open(path).read().rstrip() == command]