2012-10-02 55 views
0

通常,通過運行shutdown.sh腳本(或批處理文件)關閉Apache Tomcat。在某些情況下,例如當Tomcat的Web容器託管一個使用多線程做一些瘋狂事情的​​Web應用程序時,正常運行shutdown.sh會關閉某些部分Tomcat(因爲我可以看到更多可用內存返回到系統),但Tomcat進程仍在運行。如何找到Tomcat的PID並殺死它在python中?

我試圖寫一個簡單的Python腳本:

  1. 呼叫shutdown.sh
  2. 奔跑ps -aef | grep tomcat找到與Tomcat的任何過程引用
  3. 如果適用,殺死與kill -9 <PID>
過程

這是我到目前爲止(作爲原型 - 我是嶄新的Python BTW):

#!/usr/bin/python 

# Imports 
import sys 
import subprocess 

# Load from imported module. 
if __init__ == "__main__": 
    main() 

# Main entry point. 
def main(): 
    # Shutdown Tomcat 
    shutdownCmd = "sh ${TOMCAT_HOME}/bin/shutdown.sh" 
    subprocess.call([shutdownCmd], shell=true) 

    # Check for PID 
    grepCmd = "ps -aef | grep tomcat" 
    grepResults = subprocess.call([grepCmd], shell=true) 

    if(grepResult.length > 1): 
     # Get PID and kill it. 
     pid = ??? 
     killPidCmd = "kill -9 $pid" 
     subprocess.call([killPidCmd], shell=true) 

    # Exit. 
    sys.exit() 

我與中部掙扎 - 與獲得grep結果,檢查,看看他們的大小大於1(因爲grep總是回到自己的引用,至少1結果總是被退回, methinks),然後解析返回的PID並將其傳遞到killPidCmd。提前致謝!

回答

1

你需要grepResults = subprocess.check_output([grepCmd], shell=true)更換grepResults = subprocess.call([grepCmd], shell=true),如果你想保存命令的結果grepResults的字符串。然後你可以使用split將其轉換爲數組,而數組的第二個元素將是pid:pid = int(grepResults.split()[1])'

但是這隻會殺死第一個進程。如果多於一個打開,它並不會殺死所有進程。爲了做到這一點,你會寫:

grepResults = subprocess.check_output([grepCmd], shell=true).split() 
for i in range(1, len(grepResults), 9): 
    pid = grepResults[i] 
    killPidCmd = "kill -9 " + pid 
    subprocess.call([killPidCmd], shell=true) 
+0

哇 - 偉大的答案,謝謝@Ionut Hulub(+1)!快速跟進 - 一旦我獲得了'pid',如何將它添加到'killPidCmd'?我可以使用'killPidCmd ='kill -9 $ pid'還是需要使用別的東西?再次感謝! – IAmYourFaja

+0

我修改了代碼 –

+0

不要忘記「kill -9」之後的空格:) – Sandro

1

您可以將「c」添加到ps,以便只打印命令而不打印參數。這將阻止抓住匹配自己。

我不確定tomcat是否顯示爲Java應用程序,所以這可能不起作用。

PS:從谷歌搜索得到這個:「grep包括自我」,第一次有這個解決方案。

編輯:我的壞!那麼這樣的事情呢?

p = subprocess.Popen(["ps caux | grep tomcat"], shell=True,stdout=subprocess.PIPE) 
out, err = p.communicate() 
out.split()[1] #<-- checkout the contents of this variable, it'll have your pid! 

基本上「走出去」將有計劃輸出,你可以讀/操縱

+0

感謝提示@Sandro(+1) - 但是這並不能回答我的問題。我試圖解析grep的結果,使用它獲得一個變量'pid',然後將'pid'傳遞給'killPidCmd',以便它可以在shell上執行。任何想法 - 再次感謝! – IAmYourFaja

+0

嗯,好的抱歉,我不明白這個問題,檢查我的編輯。 – Sandro

+0

再次感謝@Sandro - 你可以看看Ionut Hulub的回答下的評論 - 我對你有同樣的問題! – IAmYourFaja

0

創建子進程來運行ps和字符串輸出與grep匹配是沒有必要的。 Python具有很好的字符串處理功能,Linux可以在/ proc中公開所有需要的信息。 procfs掛載是命令行實用程序獲取此信息的地方。不妨直接去源碼。

import os 

SIGTERM = 15 

def pidof(image): 
    matching_proc_images = [] 
    for pid in [dir for dir in os.listdir('/proc') if dir.isdigit()]: 
     lines = open('/proc/%s/status' % pid, 'r').readlines() 
     for line in lines: 
      if line.startswith('Name:'): 
       name = line.split(':', 1)[1].strip() 
       if name == image: 
        matching_proc_images.append(int(pid)) 

    return matching_proc_images 


for pid in pidof('tomcat'): os.kill(pid, SIGTERM)