如何通过Python查找进程的pid? 使用子流程库

问题描述

朋友:

我正在Linux中运行脚本:

我可以使用ps命令来获取该过程。

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

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


EDIT-01

我的意思是,我想使用python脚本查找正在运行的脚本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",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脚本的python进程的pid的示例。这可能包括当前流程,但是主要用例是检查 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)