Zapobiegaj zamykaniu Pythona na ctrl-D

0

Często zdarza mi się, że:

  1. Używam Pythona w interaktywnej sesji terminalowej
  2. Przypadkowo wpisuję coś za pomocą niezrównoważonych nawiasów
  3. Python wyświetla mi ...monit, oczekując, że wprowadzę inny wiersz kodu
  4. W celu powrotu do wiersza polecenia Python instynktownie wpisuję ctrl-D(znak końca transmisji)
  5. Zamiast wracać do >>>monitu, proces Pythona kończy się natychmiast, tracąc wszystkie dane z mojej interaktywnej sesji

Chciałbym, żeby to się już więcej nie zdarzyło. Dlatego moje pytania to:

  • Czy istnieje sposób, aby zapobiec zamknięciu Pythona po ctrl-Dnaciśnięciu ?;

  • To może być pobożne życzenie, ale czy jest jakiś sposób, aby zmusić ctrl-Dmnie do powrotu do monitu Python, ponieważ wciąż tego oczekuję?

Używam Pythona 3.6 zainstalowanego z MacPorts na Macu, ale myślę, że jest to pytanie dość niezależne od platformy. Wierzę, że ta instalacja korzysta z biblioteki Gnu Readline do interakcji użytkownika w razie potrzeby.

Nataniel
źródło
Jestem ciekawy, skąd wziął się twój refleks trafienia w Ctrl-D. W jakim programie wyciąga cię z takiego podpowiedzi bez wychodzenia? Myślę, że „właściwym” rozwiązaniem jest Ctrl-C, który zarejestruje się jako wyjątek KeyboardInterrupt i anuluje bieżący monit.
Daniel H
@DanielH Właściwie nie jestem pewien, ale prawdopodobnie pochodzi głównie z bash.
Nathaniel

Odpowiedzi:

0

W podstawowych programach, które używają trybu „gotowanego”, takiego jak cat, Ctrl+Dzaczepia się o warstwę tty jako znak eof - nie jest wysyłany bezpośrednio do procesu, ale generuje warunek „EOF”, powodując, że proces nagle otrzymuje wartość 0- wynik bajtu z jego read(stdin)wywołania. (Proces może po prostu zanotować warunek i kontynuować).

Teoretycznie, ponieważ Python używa Readline, nie ma na to wpływu; wykorzystuje terminal w trybie „cbreak” i pozwala Readline na obsługę wszystkich znaków specjalnych, w tym Ctrl + D. (Oznacza to, że naciśnięcie klawisza zwróci po prostu „\ x04” z odczytu, który następnie jest obsługiwany wewnętrznie przez powiązania Readline).

Jednak Readline automatycznie wiąże te same znaki sterujące, które widzi już związane na warstwie tty, i nie ma opcji kontrolowania tego z poziomu Pythona. (Chociaż ma opcję ~ / .inputrc, wydaje się, że jest ignorowana w Pythonie).

czy istnieje sposób, aby zapobiec zamknięciu Pythona po naciśnięciu klawisza Ctrl-D ?;

Wydaje się więc, że nie ma sposobu, aby zatrzymać readline Pythona z obsługi Ctrl + D jak EOF chyba warstwa tty ma EOF zobowiązany do czegoś innego (ale nie całkowicie niezwiązanego). Jedyną opcją jest tymczasowe przedefiniowanie znaku EOF, aby był czymś innym niż Ctrl + D na warstwie tty (użycie stty eof), i przedefiniowanie go do poprawnej wartości po wyjściu.

Spróbuj umieścić to w pliku $ PYTHONSTARTUP:

if True:
    import atexit, os
    os.system("stty eof ^X")
    atexit.register(lambda: os.system("stty eof ^D"))

(Pamiętaj, że całkowicie niezdefiniowane eoftutaj nie zadziała - jeśli Readline znajdzie wartość null, domyślnie przyjmie Ctrl + D).

Niezależnie od powyższego, jeśli wpiszesz niedopasowany nawias, jaki jest właściwy sposób na zamknięcie ...monitu i powrót do tego >>>bez uruchamiania kodu, który wprowadziłem?

Prasa Ctrl+C. Python akceptuje SIGINT, aby to zrobić, podobnie jak większość powłok.

grawitacja
źródło
Python ma readlinemoduł. Możesz go użyć do powiązania ^ D z brakiem operacji podczas uruchamiania.
Daniel H