2011-10-04 234 views
32

我正在尝试根据进程ID来查找进程是否正在运行。代码如下,基于论坛上的帖子之一。我不能考虑进程名称,因为有多个进程使用相同的名称运行。检查一个进程是否正在Python中运行(在Linux/Unix中)

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。

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

+0

@Cody:我没有看远远不够去看看! –

回答

39

尝试:

os.kill(pid, 0) 

能成功(什么都不做),如果该进程存在,或者抛出一个异常(你可以赶上)如果进程不存在。

+0

在posix系统上是最好的办法。 –

+4

它会杀死进程吗? – sharafjaffri

+6

不,它不会真的杀死这个过程。 'kill'是一个命名不清的系统调用。 – user9876

3

如果该进程属于同一用户的检查过程,那么可以试试kill吧。如果你使用信号0,kill不会发送任何东西,但仍然允许你告诉过程是否可用。

kill(2)

If sig is 0, then no signal is sent, but error checking is still performed; this can be used to check for the existence of a process ID or process group ID.

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

+0

我不会保证在Windows上的这种行为,虽然它在Linux上会很好。 –

+0

考虑到以'ps |开头的OP grep',我不认为这是一个问题;) – viraptor

5

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

9

这是一个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作品(如Python 2.7版),而os.getpgid不会但是 Windows版本调用TerminateProcess(),它将“无条件地导致进程退出”,所以我预测它不会安全地返回所需的信息,而不会实际上终止进程,如果它存在的话。

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

+0

这工作得很好。感谢所有的答复。 – shash

+0

'os.kill(,0)''导致'错误87参数是不正确的'作为python 2.7.6在Windows –

11

在我看来,最简单的答案(albiet也许不是理想的),会改变你的

ps -ef | grep <pid> 

要:

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

这会忽略含有grep的搜索过程中上市您正在尝试查找的进程的PID。

看来user9876的答案是更“pythonic”,但是。

+0

多数民众赞成在通常我怎么做。 – vinodkone

+0

这不是防水的。更好的办法(在linux上) os.path.lexists('/ proc /%s'%pid) – Willem

+0

这个答案(与asker的实现一起)是不正确的。从'ps'解析输出是一个糟糕的主意,特别是对于这样的事情。作为一个简单的实验,我使用了161的PID,并且还返回了一个PID为1613的进程。如果您需要使用grep,那么您需要使用正则表达式来防止误报。无论如何,这与大多数情况无关,因为正确答案(如果您决定使用Linux shell)应该是'ps PID'。 – Six

-2

你必须找两次..

像这样:

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

如果返回True那么这实际上是运行!

+0

假设PID在该列表中是唯一的,这是一个坏主意。或者更具体地说,PID是唯一的,但它可能存在于其他列中。例如,127存在于PID“127”,“1127”和本地回送IP地址中。相反,运行“ps -eo pid | egrep^71676 $”。 – Olli

+0

这个,根据定义,不会找到任何东西.... –

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

3

我知道这是旧的,但我已经使用这个,它似乎工作;你可以做一个快速适应从进程名称转换进程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 
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' 
相关问题