检查进程是否在Python中运行(在Linux / Unix中)

时间:2011-10-04 11:28:17

标签: python

我正在尝试根据进程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。

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

11 个答案:

答案 0 :(得分:41)

尝试:

os.kill(pid, 0)

如果进程存在,应该成功(并且不执行任何操作),如果进程不存在,则抛出异常(可以捕获)。

答案 1 :(得分:10)

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

ps -ef | grep <pid>

要:

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

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

然而,似乎user9876的答案更加“pythonic”。

答案 2 :(得分:8)

这有点像kludge,但在* 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,请告诉我们,因为在这种情况下,这些解决方案都不可接受。

答案 3 :(得分:8)

您可以检查文件夹/ p​​roc / [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?

答案 4 :(得分:7)

我知道这已经过时了,但我已经习惯了它,它似乎有效;您可以快速调整以从流程名称转换为流程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

答案 5 :(得分:5)

如果您不介意使用外部模块,我建议psutil。它是跨平台的,比产生子shell更容易使用,仅用于查找正在运行的进程。

答案 6 :(得分:3)

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

来自kill(2)

  

如果sig为0,则不发送任何信号,但错误检查仍然存在   执行;这可以用于检查进程ID的存在   或处理组ID。

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

答案 7 :(得分:2)

在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

答案 8 :(得分:2)

在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

答案 9 :(得分:0)

最近我必须列出正在运行的进程,并且这样做了:

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'

答案 10 :(得分:-2)

你必须找到它两次..

像这样:

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

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