While using python\'s cmd.Cmd to create a custom CLI, how do I tell the handler to abort the current line and give me a new prompt?
Here is a minimal example:
I wanted to do the same, so I searched for it and created basic script for understanding purposes, my code can be found on my GitHub
So, In your code,
instead of this
if __name__ == '__main__':
console = Console()
console.cmdloop()
Use this,
if __name__ == '__main__':
console = Console()
try:
console.cmdloop()
except KeyboardInterrupt:
print ("print sth. ")
raise SystemExit
Hope this will help you out. well, it worked for me.
You can check out the signal
module: http://docs.python.org/library/signal.html
import signal
oldSignal = None
def handler(signum, frame):
global oldSignal
if signum == 2:
print "ctrl+c!!!!"
else:
oldSignal()
oldSignal = signal.signal(signal.SIGINT, handler)
I prefer the signal method, but with just pass. Don't really care about prompting the user with anything in my shell environment.
import signal
def handler(signum, frame):
pass
signal.signal(signal.SIGINT, handler)
I'm currently working on a creation of a Shell by using the Cmd module. I've been confronted with the same issue, and I found a solution.
Here is the code:
class Shell(Cmd, object)
...
def cmdloop(self, intro=None):
print(self.intro)
while True:
try:
super(Shell, self).cmdloop(intro="")
break
except KeyboardInterrupt:
print("^C")
...
Now you have a proper KeyboardInterrupt (aka CTRL-C) handler within the shell.
Instead of using signal handling you could just catch the KeyboardInterrupt
that cmd.Cmd.cmdloop()
raises. You can certainly use signal handling but it isn't required.
Run the call to cmdloop()
in a while loop that restarts itself on an KeyboardInterrupt
exception but terminates properly due to EOF.
import cmd
import sys
class Console(cmd.Cmd):
def do_EOF(self,line):
return True
def do_foo(self,line):
print "In foo"
def do_bar(self,line):
print "In bar"
def cmdloop_with_keyboard_interrupt(self):
doQuit = False
while doQuit != True:
try:
self.cmdloop()
doQuit = True
except KeyboardInterrupt:
sys.stdout.write('\n')
console = Console()
console.cmdloop_with_keyboard_interrupt()
print 'Done!'
Doing a CTRL-c just prints a new prompt on a new line.
(Cmd) help
Undocumented commands:
======================
EOF bar foo help
(Cmd) <----- ctrl-c pressed
(Cmd) <------ctrl-c pressed
(Cmd) ddasfjdfaslkdsafjkasdfjklsadfljk <---- ctrl-c pressed
(Cmd)
(Cmd) bar
In bar
(Cmd) ^DDone!
You can catch the CTRL-C signal with a signal handler. If you add the code below, the interpreter refuses to quit on CTRL-C:
import signal
def handler(signum, frame):
print 'Caught CTRL-C, press enter to continue'
signal.signal(signal.SIGINT, handler)
If you don't want to press ENTER after each CTRL-C, just let the handler do nothing, which will trap the signal without any effect:
def handler(signum, frame):
""" just do nothing """