Ich schrieb eine Python 3.5-Anwendung mit dem Cmd-Modul. Das letzte, was ich implementieren möchte, ist die richtige Handhabung des CTRL-C (Sigint) -Signals. Ich mag es mehr oder weniger die Art und Weise Bash verhalten tut es:Handle CTRL-C in Python-Cmd-Modul
- Druck^C dem Punkt, an dem Cursor
- klar den Puffer ist, so dass die Eingabe von Text
- Springen zum nächsten gelöscht Druckzeile, die Eingabeaufforderung, und warten Eingangs
Grundsätzlich gilt:
/test $ bla bla bla|
# user types CTRL-C
/test $ bla bla bla^C
/test $
hier Code als runnable vereinfacht Beispiel:
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()
Das funktioniert fast. Wenn ich CTRL-C drücke, wird^C am Cursor gedruckt, aber ich muss noch die Eingabetaste drücken. Dann bemerkt die precmd
-Methode ihr self._interrupted
-Flag, das von dem Handler festgelegt wird, und gibt eine leere Zeile zurück. Das ist soweit ich es könnte, aber ich möchte irgendwie das nicht eingeben müssen.
Ich denke, ich muss irgendwie zwingen, die input()
zurückzukehren, hat jemand Ideen?
Es würde helfen, eine kleine ausführbare Probe zu haben. Ohne Ihren Code zu schreiben, wie Sie gerade vorgehen, würde es ausreichen, ein '' \ n'' oder ein Leerzeichen nach 'stdout' zu schreiben? Das heißt, sobald der Signal-Handler ausgelöst wurde, wird am Ende von ''^C'' ein Zeilenumbruch angefügt. – tijko
@tijko Bearbeiten Sie den Beitrag, indem Sie das Snippet durch ein ausführbares Beispiel ersetzen. Ich habe versucht, eine neue Zeile zu schreiben, um stdout (es ist eigentlich standardmäßig durch die Druckmethode gemacht), aber es funktioniert nicht, und warum sollte es? Es würde erfordern, dass stdin von stdout gefüttert wird, was nicht der Fall ist, es ist nicht piped. – wujek
Yeah, du hast Recht, ich habe nicht in Bezug auf Befehlszeile stdin Prompt gedacht. @ DanGetz hat eine Antwort, die Ihren Bedürfnissen entspricht, glaube ich. Es ist auch sauberer, keine Notwendigkeit, Signalhandler zu setzen oder Flags zu setzen. Nach deinem Kommentar habe ich begonnen, entlang der Linien der Umleitung von stdin zu denken, du kannst dich anpassen, wie auch immer du es brauchst. – tijko