Al usar el cmd.Cmd de python para crear una CLI personalizada, ¿cómo le digo al controlador que cancele la línea actual y me proporcione una nueva solicitud?Mejor manejo de KeyboardInterrupt en el intérprete de línea de comandos cmd.Cmd
Aquí está un ejemplo mínimo:
# console_min.py
# run: 'python console_min.py'
import cmd, signal
class Console(cmd.Cmd):
def __init__(self):
cmd.Cmd.__init__(self)
self.prompt = "[test] "
signal.signal(signal.SIGINT, handler)
def do_exit(self, args):
return -1
def do_EOF(self, args):
return self.do_exit(args)
def preloop(self):
cmd.Cmd.preloop(self)
self._hist = []
self._locals = {}
self._globals = {}
def postloop(self):
cmd.Cmd.postloop(self)
print "Exiting ..."
def precmd(self, line):
self._hist += [ line.strip() ]
return line
def postcmd(self, stop, line):
return stop
def emptyline(self):
return cmd.Cmd.emptyline(self)
def handler(self, signum, frame):
# self.emptyline() does not work here
# return cmd.Cmd.emptyline(self) does not work here
print "caught ctrl+c, press return to continue"
if __name__ == '__main__':
console = Console()
console.cmdloop()
Además ayuda es muy apreciada.
Pregunta original y más detalles: [Actualmente, las siguientes sugerencias se han integrado en esta pregunta, sigue buscando una respuesta. Actualizado para corregir un error.]
Desde entonces he intentado mover el controlador a una función fuera del ciclo para ver si era más flexible, pero no parece ser así.
Estoy usando Python's cmd.Cmd module para crear mi propio intérprete de línea de comandos para administrar la interacción con algún software. A menudo presiono ctrl + c esperando el comportamiento popular similar a un intérprete de comandos al devolver un nuevo prompt sin actuar en cualquier comando que se haya tipeado. Sin embargo, simplemente sale. Intenté atrapar las excepciones KeyboardInterrupt en varios puntos del código (preloop, etc.) en vano. He leído un poco en sigints pero no sé exactamente cómo encaja aquí.
ACTUALIZACIÓN: A partir de las sugerencias a continuación, traté de implementar la señal y pude hacerlo de tal manera que ctrl + c ahora no sale de la CLI pero imprime el mensaje. Sin embargo, mi nuevo problema es que parece que no puedo decirle a la función del controlador (ver a continuación) que haga mucho más que imprimir. Me gustaría ctrl + c para abortar la línea actual y darme un nuevo aviso.
Esto * parece * converger en una solución, pero no sé cómo integrarlo en mi propio código (arriba). Tengo que descubrir la línea 'super'. Necesito tratar de hacer que esto funcione en algún momento en el futuro. –
En Python 2.x, 'cmd.Cmd' es una * clase de estilo antiguo *, por lo que' super' no funcionará. Ver [esta pregunta] (http://stackoverflow.com/questions/770134). –
¿Por qué tienes que llamar 'postloop()' a ti mismo? –