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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3761639/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 12:36:56  来源:igfitidea点击:

How do you get the process ID of a program in Unix or Linux using Python?

python

提问by James

I'm writing some monitoring scripts in Python and I'm trying to find the cleanest way to get the process ID of any random running program given the name of that program

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

something like

就像是

ps -ef | grep MyProgram

I could parse the output of that however I thought there might be a better way in python

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

采纳答案by lunaryorn

Try pgrep. Its output format is much simpler and therefore easier to parse.

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

回答by Derek Swingley

回答by Mark

If you are not limiting yourself to the standard library, I like psutilfor this.

如果您不限制自己使用标准库,那么我喜欢psutil

For instance to find all "python" processes:

例如查找所有“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}]

回答by user3818650

For Windows

对于 Windows

A Way to get all the pids of programs on your computer without downloading any modules:

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

If you just wanted one program or all programs with the same name and you wanted to kill the process or something:

如果您只想要一个程序或所有具有相同名称的程序,并且您想终止该进程或其他内容:

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)

That was just a paste of my process kill program I could make it a whole lot better but it is okay.

那只是我的进程终止程序的粘贴,我可以让它变得更好,但没关系。

回答by Sand3r

The task can be solved using the following piece of code, [0:28] being interval where the name is being held, while [29:34] contains the actual pid.

该任务可以使用以下代码来解决,[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 DevPlayer

Also: Python: How to get PID by process name?

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

Adaptation to previous posted answers.

适应以前发布的答案。

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']

回答by Fernando

For posix (Linux, BSD, etc... only need /proc directory to be mounted) it's easier to work with os files in /proc

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

Works on python 2 and 3 ( The only difference is the Exception tree, therefore the "except Exception", which i dislike but kept to maintain compatibility. Also could've created custom exception.)

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

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

Sample Output (it works like pgrep):

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

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

回答by Eyal Levin

With psutil:

psutil

(can be installed with [sudo] pip install 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]

回答by Derek Veit

This is a simplified variation of Fernando's answer. This is for Linux and either Python 2 or 3. No external library is needed, and no external process is run.

这是费尔南多答案的简化变体。这适用于 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]

Only the first matching process found will be returned, which works well for some purposes. To get the PIDs of multiple matching processes, you could just replace the returnwith yield, and then get a list with pids = list(get_command_pid(command)).

只会返回找到的第一个匹配进程,这对于某些目的很有效。为了得到多个匹配进程的PID,你可以只更换returnyield,然后得到一个列表pids = list(get_command_pid(command))

Alternatively, as a single expression:

或者,作为单个表达式:

For one process:

对于一个过程:

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

For multiple processes:

对于多个进程:

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