viernes, 20 de julio de 2012

subprocess en python

Vamos a ver cómo hacer un script de parada/arranque de un servicio utilizando subprocess.

subprocess nos va a permitir lanzar un comando y esperar a que este termine, y una vez terminado, ver en qué estado ha finalizado.

El siguiente ejemplo se puede utilizar para llevar a cabo un reinicio automático de un servicios (jboss por ejemplo) y estar seguros de que el servicio es detenido y arrancado correctamente:

#!/usr/bin/env python
# -*- coding: iso-8859-15 -*-

import subprocess
script_arranque='/etc/init.d/jboss start'
script_parada='/etc/init.d/jboss stop'
#paramos jboss
pipe=subprocess.Popen(script_arranque, stdout=subprocess.PIPE, shell=True)
estado=pipe.wait()
out, err = pipe.communicate()
if estado == 0:
        print "Estado salida correcto."
else:
        print "Salida de error: " + str(err) 
'''en este caso, el único proceso java que corre es jboss, si hubiese más de uno, la siguiente opción no sería válida ' ' '
pipe=subprocess.Popen('pidof java', stdout=subprocess.PIPE, shell=True)
out, err = pipe.communicate()
pid = out.strip()
if pid != '':
        print "El proceso no se ha detenido, matamos el pid: " + pid + "."
        pipe=subprocess.Popen('kill -9 ' + pid, stdout=subprocess.PIPE, shell=True)
#Ya está parado jboss, ahora lo arrancamos
pipe=subprocess.Popen(script_parada, stdout=subprocess.PIPE, shell=True)
estado=pipe.wait()
out, err = pipe.communicate()
if estado == 0:
        print "Estado salida correcto."
else:
        print "Salida de error: " + str(err)


Un detalle a tener en cuenta cuando utilicemos subprocess es que si utilizamos la shell (shell=True) el comando que pasemos será una cadena, mientras que si no utilizamos la shell (shell=False) el comando se ha de pasar como una lista. Por ejemplo, para ejecutar un ls -la:

Con shell:
    subprocess.Popen('ls -la', shell=True)
Sin shell:
    subprocess.Popen(['ls','-la'], shell=False)


Para ver el estado en el que finaliza, podemos hacerlo mediante:

estado=pipe.wait()

ó

estado=pipe.returncode


Y para ver la salida estándar y la salida de error, haremos uso de communicate:

out, err = pipe.communicate()

No hay comentarios:

Publicar un comentario

Obtener informacion de repositorios a través de los metadatos .git publicados por error

 A raiz de CTF realizado recientemente, me ha parecido interesante publicar este post sobre los errores de seguridad que se encuentran en mu...