Napisałem aplikację Python 3.5 za pomocą modułu cmd. Ostatnią rzeczą, którą chciałbym zaimplementować, jest właściwa obsługa sygnału CTRL-C (sigint). Chciałbym, aby zachowywać się mniej więcej sposób atakujących robi:Uchwyt CTRL-C w module cmd Python
- drukuj^C w punkcie kursor znajduje
- wyczyścić bufor, tak aby wprowadzić tekst zostanie usunięty
- Przejście do następnego linia, wydrukować wiersz, i czekać na wejście
Zasadniczo:
/test $ bla bla bla|
# user types CTRL-C
/test $ bla bla bla^C
/test $
Tutaj jest uproszczony kod jako runnable próbka:
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()
To prawie działa. Kiedy naciśniesz CTRL-C,^C zostanie wydrukowane przy kursorze, ale nadal muszę nacisnąć enter. Następnie metoda precmd
odnotowuje flagę self._interrupted
ustawioną przez procedurę obsługi i zwraca pustą linię. To jest tak daleko, jak mogłem to wziąć, ale nie chciałbym w żaden sposób naciskać tego wejścia.
Chyba muszę jakoś zmusić do powrotu input()
, czy ktoś ma pomysły?
Pomoże to mieć małą próbkę, którą można uruchomić. Nie uruchamiając swojego kodu, w jaki sposób obecnie się o to rozprawiasz, wystarczy napisać ''\ n'' lub puste na' stdout'? To jest po tym, jak obsługa sygnału zostaje potknięta w kierunku znaku nowej linii na końcu ''^ C'' – tijko
@tijko Edytował post, zamieniając fragment kodu na próbkę działającą. Próbowałem napisać znak nowej linii na standardowe wyjście (domyślnie jest to metoda drukowania), ale to nie działa i dlaczego? Wymagałoby to, aby stdin był podawany ze standardowego wyjścia, co nie ma miejsca, nie jest podłączony do instalacji rurowej. – wujek
Tak, masz rację, nie myślałem w terminach linii poleceń STDIN. @DanGetz ma odpowiedź, która będzie pasować do twoich potrzeb. Jest także czystszy, nie trzeba ustawiać obsługi sygnału ani ustawiać flag. Po twoim komentarzu zacząłem myśleć wzdłuż linii przekierowania standardowego wejścia, możesz dostosować się do tego, czego potrzebujesz. – tijko