2011-10-04 235 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' 
相關問題