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


72

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

就像是

ps -ef | grep MyProgram

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


如果您想跨平台工作(例如,在Linux,Mac,Solaris等上也是如此),没有比解析pf输出更好的方法了。如果是针对单个非常特定的平台,请编辑您的Q,以添加明显重要的信息(您需要定位的确切OS版本)以及标签!
Alex Martelli 2010年

您可以直接在python中解析ps的输出
mmmmmm 2010年

Answers:


15

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



22

如果您不局限于标准库,那么我喜欢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}]

您能提供一个例子吗?
克里希纳(Krishna)Oza's

缺乏例子
Paullo

8

另外: 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']

4

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]

3

对于Windows

一种无需下载任何模块即可获取计算机上所有程序的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)

那只是我的进程终止程序的一个粘贴,我可以使它更好很多,但是还可以。


1

对于posix(Linux,BSD等……仅需挂载/ proc目录),使用/ proc中的os文件更容易

适用于python 2和3(唯一的区别是Exception树,因此是“ except除外”,我不喜欢它,但一直保持兼容性。还可以创建自定义异常。)

#!/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

0

这是费尔南多答案的简化变体。这适用于Linux和Python 2或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,你可以只更换returnyield,然后得到一个列表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]

-1

可以使用以下代码解决该任务,[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)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.