Ho scritto un'applicazione Python 3.5 utilizzando il modulo cmd. L'ultima cosa che vorrei implementare è la corretta gestione del segnale CTRL-C (sigint). Desidero a comportarsi più o meno come Bash fa:Gestire CTRL-C nel modulo cmd Python
- stampa^C nel punto del cursore è
- chiaro il buffer in modo che il testo inserito viene eliminato
- saltare al successivo linea, stampare la richiesta, e attendere per l'ingresso
in sostanza:
/test $ bla bla bla|
# user types CTRL-C
/test $ bla bla bla^C
/test $
Qui è semplificato codice come eseguibile 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()
Questo funziona quasi. Quando premo CTRL-C,^C viene stampato sul cursore, ma devo ancora premere Invio. Quindi, il metodo notifica il flag self._interrupted
impostato dal gestore e restituisce una riga vuota. Questo è il massimo che potrei prendere, ma mi piacerebbe in qualche modo non dover premere quel tasto.
Immagino di dover in qualche modo forzare il input()
a tornare, qualcuno ha idee?
Sarebbe utile avere un piccolo campione eseguibile. Senza eseguire il tuo codice come lo stai attualmente facendo, scriverebbe un ''\ n'' o vuoto per' stdout' è sufficiente? Questo è il modo in cui il gestore del segnale è scattato virare una nuova riga alla fine di ''^ C'' – tijko
@tijko Modificato il post sostituendo lo snippet con un campione eseguibile. Ho provato a scrivere una nuova riga su stdout (in realtà è eseguita di default dal metodo di stampa), ma non funziona, e perché dovrebbe? Richiederebbe che lo stdin sia alimentato dallo stdout, il che non è il caso, non è collegato. – wujek
Sì, hai ragione, non stavo pensando in termini di prompt della riga di comando. @ DanGetz ha una risposta che soddisferà le tue esigenze credo. Anche per la pulizia, non è necessario impostare il gestore di segnale o impostare le bandiere. Dopo il tuo commento, ho iniziato a pensare anche a come reindirizzare lo stdin, puoi adattarlo a qualsiasi necessità. – tijko