Comment trouver le PID de Tomcat et le tuer en python ?
Question
Normalement, on arrête Apache Tomcat en exécutant son shutdown.sh
script (ou fichier batch).Dans certains cas, par exemple lorsque le conteneur Web de Tomcat héberge une application Web qui fait des choses folles avec le multithread, l'exécution shutdown.sh
s'éteint gracieusement quelques certaines parties de Tomcat (car je peux voir plus de mémoire disponible revenir au système), mais le processus Tomcat continue de s'exécuter.
J'essaie d'écrire un script Python simple qui :
- Appels
shutdown.sh
- Fonctionne
ps -aef | grep tomcat
pour trouver n'importe quel processus avec Tomcat référencé - Le cas échéant, tue le processus avec
kill -9 <PID>
Voici ce que j'ai jusqu'à présent (en tant que prototype - je suis tout nouveau sur 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()
J'ai du mal avec la partie médiane - pour obtenir le grep
résultats, en vérifiant si leur taille est supérieure à 1 (puisque grep
renvoie toujours une référence à lui-même, au moins 1 résultat sera toujours renvoyé, je pense), puis analyser le PID renvoyé et le transmettre au killPidCmd
.Merci d'avance!
La solution
tu dois remplacer grepResults = subprocess.call([grepCmd], shell=true)
avec grepResults = subprocess.check_output([grepCmd], shell=true)
si vous souhaitez enregistrer les résultats de la commande dans grepResults.Ensuite, vous pouvez utiliser split pour convertir cela en tableau et le deuxième élément du tableau sera le pid : pid = int(grepResults.split()[1])'
Cependant, cela ne fera que tuer le premier processus.Cela ne tue pas tous les processus si plusieurs sont ouverts.Pour ce faire, il faudrait écrire :
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)
Autres conseils
Vous pouvez ajouter "c" à ps pour que seule la commande et non les arguments soient imprimés.Cela empêcherait grab de s'adapter à lui-même.
Je ne sais pas si Tomcat apparaît comme une application Java, donc cela pourrait ne pas fonctionner.
PS :J'ai obtenu ça en cherchant sur Google :"grep inclut self" et le premier coup avait cette solution.
MODIFIER:Ma faute!OK, quelque chose comme ça alors ?
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!
Fondamentalement, "out" aura la sortie du programme sous forme de chaîne que vous pourrez lire/manipuler
Création de processus enfants à exécuter ps
et la chaîne correspond à la sortie avec grep
n'est pas nécessaire.Python a une excellente gestion des chaînes « intégrée » et Linux expose toutes les informations nécessaires dans /proc.Le montage procfs est l'endroit où les utilitaires de ligne de commande obtiennent ces informations.Autant aller directement à la source.
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)