Pregunta

Normalmente, uno cierra Apache Tomcat ejecutando su shutdown.sh script (o archivo por lotes).En algunos casos, como cuando el contenedor web de Tomcat aloja una aplicación web que hace algunas cosas locas con subprocesos múltiples, ejecuta shutdown.sh se apaga con gracia alguno partes de Tomcat (como puedo ver, más memoria disponible regresa al sistema), pero el proceso de Tomcat continúa ejecutándose.

Estoy intentando escribir un script Python simple que:

  1. llamadas shutdown.sh
  2. Carreras ps -aef | grep tomcat para encontrar cualquier proceso con Tomcat referenciado
  3. Si corresponde, finaliza el proceso con kill -9 <PID>

Esto es lo que tengo hasta ahora (como prototipo; por cierto, soy nuevo en 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()

Estoy luchando con la parte media - con la obtención de la grep resultados, comprobando si su tamaño es mayor que 1 (ya que grep siempre devuelve una referencia a sí mismo, siempre se devolverá al menos 1 resultado, creo), y luego analiza ese PID devuelto y lo pasa al killPidCmd.¡Gracias de antemano!

¿Fue útil?

Solución

necesitas reemplazar grepResults = subprocess.call([grepCmd], shell=true) con grepResults = subprocess.check_output([grepCmd], shell=true) si desea guardar los resultados del comando en grepResults.Luego puedes usar split para convertir eso en una matriz y el segundo elemento de la matriz será el pid: pid = int(grepResults.split()[1])'

Sin embargo, eso sólo matará el primer proceso.No mata todos los procesos si hay más de uno abierto.Para hacer eso tendrías que escribir:

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)

Otros consejos

Puede agregar "c" a ps para que solo se imprima el comando y no los argumentos.Esto impediría que grab coincida consigo mismo.

Sin embargo, no estoy seguro de si Tomcat aparece como una aplicación Java, por lo que es posible que esto no funcione.

PD:Obtuve esto buscando en Google:"grep incluye a uno mismo" y el primer resultado tenía esa solución.

EDITAR:¡Culpa mía!¿Está bien algo como esto entonces?

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!

Básicamente, "out" tendrá la salida del programa como una cadena que puedes leer/manipular.

Crear procesos secundarios para ejecutar ps y la cadena coincide con la salida con grep no es necesario.Python tiene un excelente manejo de cadenas 'integrado' y Linux expone toda la información necesaria en /proc.El montaje procfs es donde las utilidades de línea de comando obtienen esta información.También podría ir directamente a la fuente.

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)
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top