2012-07-04 11 views
14

Tengo una aplicación GTK basada en python que carga varios módulos. Se ejecuta desde el terminal (Linux) de esta manera:Reiniciar python-script desde su interior

./myscript.py --some-flag setting

Desde el programa el usuario puede descargar (usando Git) versiones más recientes. Si existe/se descarga, aparece un botón que me gustaría reiniciar el programa con contenido recién compilado (incluidas dependencias/importaciones). Preferiblemente también lo reiniciaría usando los contenidos de sys.argv para mantener todas las banderas como estaban.

Así que lo que no encuentro/necesito es un buen procedimiento de reinicio que mata la instancia actual del programa y comienza una nueva usando los mismos argumentos.

Preferiblemente, la solución también debería funcionar para Windows y Mac, pero no es esencial.

+0

lo que podría ser posible es tener el nuevo proceso que se ejecuta en paralelo a la antigua en un principio. Teóricamente, podría darle al nuevo proceso la identificación del proceso del anterior (a través de una opción de línea de comando adicional) y eliminar el anterior tan pronto como el nuevo esté en funcionamiento. –

+0

posible duplicado de [Reiniciar una secuencia de comandos python autoactualizable] (http://stackoverflow.com/questions/1750757/restarting-a-self-updating-python-script) –

Respuesta

24

Está buscando os.exec*().

+0

wow! no sabía que esto es posible gracias por señalar eso! –

+2

Esto me da un error de sintaxis inválido con python 2.7.9. – clankill3r

2

ACTUALIZACIÓN - de la respuesta anterior con un poco de ejemplo para futuras referencias

tengo runme.sh

#!/bin/bash 
kill -9 server.py 
python /home/sun/workspace/c/src/server.py & 

Y tengo server.py donde tengo que reiniciar la aplicación en sí, así que tuve:

os.system('runme.sh') 

pero eso no reinició la aplicación siguiendo a runme.sh, así que cuando utilicé esta opción:

os.execl('runme.sh', '') 

entonces yo era capaz de reiniciarse

14

Creo que esta es una respuesta más elaborada, ya que a veces puede terminar con demasiados objetos de archivo abierto y descriptores, que puede causar problemas de memoria o conexiones simultáneas a un dispositivo de red.

import os 
import sys 
import psutil 
import logging 

def restart_program(): 
    """Restarts the current program, with file objects and descriptors 
     cleanup 
    """ 

    try: 
     p = psutil.Process(os.getpid()) 
     for handler in p.get_open_files() + p.connections(): 
      os.close(handler.fd) 
    except Exception, e: 
     logging.error(e) 

    python = sys.executable 
    os.execl(python, python, *sys.argv) 
0

Sé que esta solución no es técnicamente lo que está pidiendo, pero si quieres estar 100% seguro de que todo lo liberado o no quiere depender de dependencias que sólo podría ejecutar el script desde una en otro bucle:

import os, time 

while 1: 
    os.system("python main.py") 
    print "Restarting..." 
    time.sleep(0.2) # 200ms to CTR+C twice 

a continuación, puede reiniciar main.py tan simple como:

quit() 
Cuestiones relacionadas