I wrote a Python 3.5 application using the cmd module. The last thing I would like to implement is proper handling of the CTRL-C (sigint) signal. I would like it to behave more or less the way Bash does it:
- print ^C at the point the cursor is
- clear the buffer so that the input text is deleted
- skip to the next line, print the prompt, and wait for input
Basically:
/test $ bla bla bla|
# user types CTRL-C
/test $ bla bla bla^C
/test $
Here is simplified code as a runnable sample:
import cmd
import signal
class TestShell(cmd.Cmd):
def __init__(self):
super().__init__()
self.prompt = '$ '
signal.signal(signal.SIGINT, handler=self._ctrl_c_handler)
self._interrupted = False
def _ctrl_c_handler(self, signal, frame):
print('^C')
self._interrupted = True
def precmd(self, line):
if self._interrupted:
self._interrupted = False
return ''
if line == 'EOF':
return 'exit'
return line
def emptyline(self):
pass
def do_exit(self, line):
return True
TestShell().cmdloop()
This almost works. When I press CTRL-C, ^C is printed at the cursor, but I still have to press enter. Then, the precmd
method notices its self._interrupted
flag set by the handler, and returns an empty line. This is as far as I could take it, but I would like to somehow not have to press that enter.
I guess I somehow need to force the input()
to return, does anybody have ideas?
'\n'
or blank tostdout
suffice? That is once signal handler is tripped tack a newline on the end of'^C'
– Stereoisomer