Come trovare Tomcat Pid e ucciderlo in Python?
Domanda
Normalmente, uno chiude Apache Tomcat eseguendo il suo script shutdown.sh
(o il file batch). In alcuni casi, ad esempio quando il contenitore Web di Tomcat ospita un'app Web che fa alcune cose pazze con filettatura multi-threading, eseguendo shutdown.sh
con grazia alcuni parti di Tomcat (come posso vedere più restituzione della memoria disponibile al sistema), ma il processo Tomcat continua a funzionare.
Sto cercando di scrivere un semplice script Python che:
- .
- chiama
shutdown.sh
- Esegue
ps -aef | grep tomcat
per trovare qualsiasi processo con Tomcat referencencencencencening - Se applicabile, uccide il processo con
kill -9 <PID>
Ecco cosa ho finora (come prototipo - sono nuovo di zecca a 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()
Sto lottando con la parte centrale - con l'ottenimento dei risultati
grep
, controllando di vedere se la loro dimensione è maggiore di 1 (poichégrep
restituisce sempre un riferimento a se stesso, almeno 1 risultato verrà sempre restituito, Methinks), e quindi analizzare che restituì PID e passarlo nelkillPidCmd
. Grazie in anticipo!
Soluzione
È necessario sostituire grepResults = subprocess.call([grepCmd], shell=true)
con grepResults = subprocess.check_output([grepCmd], shell=true)
se si desidera salvare i risultati del comando in Grepresults.Quindi è possibile utilizzare la divisione per convertirlo in un array e il secondo elemento dell'array sarà il PID: pid = int(grepResults.split()[1])'
che ucciderà tuttavia il primo processo.Non uccide tutti i processi se più di uno è aperto.Per fare ciò dovresti scrivere:
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)
. Altri suggerimenti
È possibile aggiungere "C" a PS in modo che solo il comando e non gli argomenti siano stampati.Questo smetterebbe di prendere la corrispondenza del suo sé.
Non sono sicuro se Tomcat si presenta come un'applicazione Java però, quindi questo potrebbe non funzionare.
PS: Ho ottenuto questo da Googling: "Grep include sé" e il primo colpo ha avuto quella soluzione.
Modifica: My Bad!Ok qualcosa del genere, allora?
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!
.
Fondamentalmente "OUT" avrà l'output del programma come una stringa che è possibile leggere / manipolare
Creazione di processi figlio per eseguire ps
e String Match L'uscita con grep
non è necessaria.Python ha una grande gestione delle stringhe 'cotte in' e Linux espone tutte le informazioni necessarie in / proc.Il supporto Procfs è dove le utilità della riga di comando ottengono queste informazioni.Potrebbe anche andare direttamente alla fonte.
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)
.