Frage

Normalerweise fährt man Apache Tomcat herunter, indem man es ausführt shutdown.sh Skript (oder Batchdatei).In einigen Fällen, beispielsweise wenn der Webcontainer von Tomcat eine Webanwendung hostet, die einige verrückte Dinge mit Multithreading macht, wird sie ausgeführt shutdown.sh schaltet sich ordnungsgemäß ab manche Teile von Tomcat (da ich sehe, dass mehr verfügbarer Speicher an das System zurückgegeben wird), aber der Tomcat-Prozess läuft weiter.

Ich versuche, ein einfaches Python-Skript zu schreiben, das:

  1. Anrufe shutdown.sh
  2. Läuft ps -aef | grep tomcat um jeden Prozess zu finden, auf den Tomcat verweist
  3. Tötet ggf. den Prozess mit kill -9 <PID>

Folgendes habe ich bisher (als Prototyp – ich bin übrigens ganz neu in Python):

#!/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()

Ich kämpfe mit dem Mittelteil – damit, das zu bekommen grep Ergebnisse und prüft, ob ihre Größe größer als 1 ist (da grep gibt immer einen Verweis auf sich selbst zurück, es wird immer mindestens ein Ergebnis zurückgegeben, denke ich), und dann wird die zurückgegebene PID analysiert und an die übergeben killPidCmd.Dank im Voraus!

War es hilfreich?

Lösung

Sie müssen ersetzen grepResults = subprocess.call([grepCmd], shell=true) mit grepResults = subprocess.check_output([grepCmd], shell=true) wenn Sie die Ergebnisse des Befehls in grepResults speichern möchten.Dann können Sie Split verwenden, um das in ein Array umzuwandeln, und das zweite Element des Arrays ist die PID: pid = int(grepResults.split()[1])'

Dadurch wird jedoch nur der erste Prozess beendet.Es werden nicht alle Prozesse beendet, wenn mehr als einer geöffnet ist.Dazu müssten Sie schreiben:

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)

Andere Tipps

Sie können „c“ zu ps hinzufügen, sodass nur der Befehl und nicht die Argumente ausgegeben werden.Dies würde verhindern, dass Grab mit sich selbst übereinstimmt.

Ich bin mir jedoch nicht sicher, ob Tomcat als Java-Anwendung angezeigt wird, daher funktioniert dies möglicherweise nicht.

PS:Habe das durch googeln bekommen:„grep Includes self“ und der erste Treffer hatte diese Lösung.

BEARBEITEN:Mein Fehler!OK, dann so etwas?

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!

Grundsätzlich gibt „out“ das Programm als Zeichenfolge aus, die Sie lesen/manipulieren können

Erstellen von untergeordneten Prozessen zur Ausführung ps und string stimmen mit der Ausgabe überein grep ist nicht nötig.Python verfügt über eine hervorragende String-Verarbeitung und Linux stellt alle benötigten Informationen in /proc bereit.Über den procfs-Mount erhalten die Befehlszeilen-Dienstprogramme diese Informationen.Könnte genauso gut direkt zur Quelle gehen.

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)
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top