【问题标题】:Check if a process is running using Python on Linux [duplicate]检查进程是否在 Linux 上使用 Python [重复]
【发布时间】:2011-11-30 14:56:00
【问题描述】:

我正在尝试根据进程 ID 查找进程是否正在运行。根据论坛上的一篇帖子,代码如下。我不能考虑进程名称,因为有多个进程以相同的名称运行。

def findProcess( processId ):
    ps= subprocess.Popen("ps -ef | grep "+processId, shell=True, stdout=subprocess.PIPE)
    output = ps.stdout.read()
    ps.stdout.close()
    ps.wait()
    return output
def isProcessRunning( processId):
    output = findProcess( processId )
    if re.search(processId, output) is None:
        return true
    else:
        return False

输出:

1111 72312 72311   0   0:00.00 ttys000    0:00.00 /bin/sh -c ps -ef | grep 71676
1111 72314 72312   0   0:00.00 ttys000    0:00.00 grep 71676

它总是返回 true,因为它可以在输出字符串中找到进程 ID。

有什么建议吗?感谢您的帮助。

【问题讨论】:

  • @Cody:我看的不够远!

标签: python linux


【解决方案1】:

试试:

os.kill(pid, 0)

如果进程存在则应该成功(并且什么都不做),或者如果进程不存在则抛出异常(您可以捕获)。

【讨论】:

  • 在 posix 系统上这是最好的方法。
  • 它会杀死进程吗?
  • 不,它实际上不会杀死进程。 kill 是一个命名错误的系统调用。
  • 看起来不错。但太糟糕了,它在 Windows 中不起作用。 WindowsError:遇到 [错误 87]。不是你的错@user9876 :)
  • @Iceberg:我已经编辑了这个问题,注意到他问的是 Linux/Unix。 (shash 的问题包括在 Windows 上通常找不到的“ps”和“grep”命令)。我建议你开始一个关于 Windows 的新问题 :-)
【解决方案2】:

我认为最简单的答案(虽然可能并不理想),就是改变你的

ps -ef | grep <pid>

收件人:

ps -ef | grep <pid> | grep -v grep

这将忽略包含您尝试查找的进程的 PID 的 grep 搜索的进程列表。

不过,user9876 的回答似乎更像“pythonic”。

【讨论】:

  • 那不是防水的。最好做(在 linux 上) os.path.lexists('/proc/%s' % pid)
  • 这个答案(连同提问者的实现)不正确。解析来自ps 的输出是一个糟糕的主意,尤其是对于这样的事情。作为一个简单的实验,我 grepped 了一个 161 的 PID,它还返回了一个 PID 为 1613 的进程。如果您需要使用grep,那么您需要使用正则表达式来防止误报。无论如何,这在很大程度上是无关紧要的,因为正确的答案(如果你决定使用 Linux shell)应该是ps PID
  • 在 shell 中,你可以做两件事之一:ps -p 12345[ -d /proc/12345 ]。不需要执行任何管道命令。
【解决方案3】:

您可以检查文件夹 /proc/[process_id] 是否存在。

 >>> import os.path
 >>> os.path.exists("/proc/0")
 False
 >>> os.path.exists("/proc/12")
 True

看到这个 SO:How do you check in Linux with Python if a process is still running?

【讨论】:

  • 我觉得这是最pythonic的
【解决方案4】:

这有点麻烦,但在 *nix 上,您可以使用 os.getpgid(pid)os.kill(pid, sig) 来测试进程 ID 的存在。

import os

def is_process_running(process_id):
    try:
        os.kill(process_id, 0)
        return True
    except OSError:
        return False

编辑:请注意,os.kill 适用于 Windows(从 Python 2.7 开始),而 os.getpgid 不会但是Windows版本调用TerminateProcess(),这将“无条件地导致进程退出”,所以我预测它不会安全地返回你想要的信息而不实际杀死进程,如果它确实存在.

如果您使用的是 Windows,请告知我们,因为在这种情况下,这些解决方案都不可接受。

【讨论】:

  • 这工作得很好。感谢所有回复。
  • os.kill(&lt;pid&gt;, 0) 在 Windows 上的 python 2.7.6 产生 error 87 the parameter is incorrect
【解决方案5】:

我知道这是旧的,但我用过它,它似乎工作;您可以快速调整以将进程名称转换为进程 ID:

 try:
    if len( os.popen( "ps -aef | grep -i 'myprocess' | grep -v 'grep' | awk '{ print $3 }'" ).read().strip().split( '\n' ) ) > 1:
        raise SystemExit(0)
 except Exception, e:
        raise e

【讨论】:

    【解决方案6】:

    如果您不介意使用外部模块,我建议您使用psutil。它是跨平台的,并且比仅仅为了查找正在运行的进程而生成子外壳更容易使用。

    【讨论】:

      【解决方案7】:

      如果该进程与检查进程属于同一用户,您可以尝试kill它。如果您使用信号 0,kill 将不会发送任何内容,但仍允许您判断进程是否可用。

      来自kill(2)

      如果 sig 为 0,则不发送信号,但仍进行错误检查 执行;这可用于检查进程 ID 是否存在 或进程组 ID。

      这应该适当地传播到 python 的方法。

      【讨论】:

      • 我不保证在 Windows 上会有这种行为,但在 Linux 上会很好。
      • 考虑到 OP 以 ps | grep 开头,我认为这不是问题 ;)
      【解决方案8】:

      在 Windows 上,另一种选择是使用 tasklist.exe:

      语法:tasklist.exe /NH /FI "PID eq processID"

      def IsProcessRunning( processId ):
          ps= subprocess.Popen(r'tasklist.exe /NH /FI "PID eq %d"' % (processId), shell=True, stdout=subprocess.PIPE)
          output = ps.stdout.read()
          ps.stdout.close()
          ps.wait()
          if processId in output:
             return True
          return False
      

      【讨论】:

        【解决方案9】:

        在 Windows 上,您可以使用 WMI。

        from win32com.client import GetObject
        GetObject('winmgmts:').ExecQuery("Select * from Win32_Process where ProcessId = " + str(pid)).count
        

        您还可以使用其他过滤器。例如,我更有可能只想判断一个进程是否按名称运行并采取行动。例如,如果 DbgView 没有运行,则启动它。

        if not GetObject('winmgmts:').ExecQuery("Select * from Win32_Process where Name = 'dbgview.exe'").count:
            subprocess.Popen(r"C:\U\dbgview.exe", shell=False)
        

        您还可以迭代并做其他有趣的事情。完整的字段列表是here

        【讨论】:

          【解决方案10】:

          最近我不得不列出正在运行的进程并这样做了:

          def check_process(process):
            import re
            import subprocess
          
            returnprocess = False
            s = subprocess.Popen(["ps", "ax"],stdout=subprocess.PIPE)
            for x in s.stdout:
                if re.search(process, x):
                    returnprocess = True
          
            if returnprocess == False:        
                print 'no process executing'
            if returnprocess == True:
                print 'process executing'
          

          【讨论】:

            【解决方案11】:

            你必须找到它两次..

            像这样:

            ps -ef | grep 71676 | sed 's/71676//' | grep 71676

            如果返回True,那么它实际上正在运行!!

            【讨论】:

            • 假设 PID 在该列表中是唯一的,这是一个坏主意。或者更具体地说,PID 是唯一的,但它可能存在于其他列中。例如,PID“127”、“1127”和本地环回IP地址中存在127。相反,运行“ps -eo pid | egrep ^71676$”。
            • 这个,根据定义,永远找不到任何东西......
            猜你喜欢
            • 2010-09-07
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-06-10
            • 2018-11-23
            相关资源
            最近更新 更多