如何通过 Python 查找进程的 pid?

How to find pid of a process by Python?

好友:

我正在 运行正在 Linux 编写脚本:

我可以使用ps命令获取进程。

ps -ef | grep "python test09.py&"

但是,我如何使用 python 代码通过给定关键字 python test09.py& 知道 运行ning 脚本的 pid?


EDIT-01

我的意思是,我想使用 python 脚本来查找 运行ning 脚本 python test09.py& 的 pid。


EDIT-02

当我使用 运行 anali 的方法时,我会得到这个错误:

Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/psutil/_psosx.py", line 363, in catch_zombie
    yield
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/psutil/_psosx.py", line 429, in cmdline
    return cext.proc_cmdline(self.pid)
ProcessLookupError: [Errno 3] No such process (originated from sysctl)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "test11.py", line 29, in <module>
    print(get_pids_by_script_name('test09.py'))
  File "test11.py", line 15, in get_pids_by_script_name
    cmdline = proc.cmdline()
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/psutil/__init__.py", line 694, in cmdline
    return self._proc.cmdline()
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/psutil/_psosx.py", line 342, in wrapper
    return fun(self, *args, **kwargs)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/psutil/_psosx.py", line 429, in cmdline
    return cext.proc_cmdline(self.pid)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/contextlib.py", line 77, in __exit__
    self.gen.throw(type, value, traceback)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/psutil/_psosx.py", line 376, in catch_zombie
    raise AccessDenied(proc.pid, proc._name)
psutil.AccessDenied: psutil.AccessDenied (pid=1)

使用此代码对 cmd 行进行字符串匹配

import psutil
# Iterate over all running process
for proc in psutil.process_iter():
    try:
        # Get process name & pid & cmd line from process object.
        processName = proc.name()
        processID = proc.pid
        print(proc.cmdline())
        print(processName , ' ::: ', processID)
    except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
        pass

如果你只想要 current 脚本的 pid,那么使用 os.getpid:

import os
pid = os.getpid()

但是,下面是使用 psutil 查找 python 进程的 pids 的示例 运行 命名的 python 脚本。这可能包括当前进程,但主要用例是检查 other 进程,因为对于 current 进程,仅使用 os.getpid如上图

sleep.py

#!/usr/bin/env python
import time
time.sleep(100)

get_pids.py

import os
import psutil


def get_pids_by_script_name(script_name):

    pids = []
    for proc in psutil.process_iter():

        try:
            cmdline = proc.cmdline()
            pid = proc.pid
        except psutil.NoSuchProcess:
            continue

        if (len(cmdline) >= 2
            and 'python' in cmdline[0]
            and os.path.basename(cmdline[1]) == script_name):

            pids.append(pid)

    return pids


print(get_pids_by_script_name('sleep.py'))

运行它:

$ chmod +x sleep.py

$ cp sleep.py other.py

$ ./sleep.py &
[3] 24936

$ ./sleep.py &
[4] 24937

$ ./other.py &
[5] 24938

$ python get_pids.py 
[24936, 24937]

使用子进程库

import subprocess
script_name = "test09.py"
ps_out = subprocess.Popen("ps -ef".split(' '), stdout=subprocess.PIPE, stderr=subprocess.PIPE).stdout.read().decode('UTF-8').split("\n") # Launch command line and gather output
for entry in ps_out:  # Loop over returned lines of ps
    if script_name in entry:
        script_pid = entry.split()[1] # retrieve second entry in line
        break
print(script_pid)