Sembra che tu stia solo eseguendo un avanzamento riga ma nessun ritorno a capo. Cambia la stampa in
print("ASD", end="\r\n")
Il problema che stai riscontrando è la differenza tra le modalità 'raw', 'cooked' e 'cbreak'. E queste modalità sono modalità del driver del terminale a livello di kernel, non modalità del codice dell'applicazione o della libreria standard o di qualsiasi altra cosa nello spazio utente. Questo è il modo vecchio stile Unix di riferirsi a questi. Posix li ha sostituiti con un set di attributi molto più granulare, anche se gli attributi Posix sono in genere capovolti insieme alle funzioni di supporto in un modo che imita le vecchie modalità "raw", "cooked" e "cbreak".
In modalità cotta, il driver del terminale stesso ha una funzionalità di modifica della riga primitiva incorporata. Gestisce il backspace, la cancellazione delle parole (praticamente il backspace di un'intera parola alla volta) e cose simili. Niente di sofisticato come gestire i tasti freccia o la cronologia o qualcosa del genere. Molto primitivo. In questa modalità, il tuo programma non vede mai nulla dal terminale finché non viene inviato il carattere di fine riga (eol), quindi il tuo programma ottiene un'intera riga e la fine della riga viene tradotta nello standard Unix \n
indipendentemente da ciò che effettivamente fa il terminale. Inoltre, come parte di questo, il driver del terminale ritrasmette i caratteri digitati al terminale in modo che l'utente possa vedere cosa stanno digitando.
In modalità 'cotta', anche il driver del terminale a livello di kernel esegue una traduzione dell'output. E parte di questo sta diventando \n
in \r\n
se necessario.
Inoltre, in modalità 'cotta' il driver del terminale gestisce caratteri speciali come Control-C (invia un SIGINT al gruppo del processo di controllo (tradotto da CPython in un'eccezione KeyboardInterrupt)) e Control-Z (invia un SIGTSTP (come un SIGSTOP, ma possono essere catturati) al gruppo di processi di controllo).
In modalità 'cbreak', la modifica della linea non viene più eseguita. Il driver del terminale assegna immediatamente ogni carattere (o breve sequenza di caratteri, come la sequenza di escape per un tasto freccia) al programma. Questi caratteri non vengono riprodotti sullo schermo e quindi, a meno che il programma non li stampi, l'utente non li vedrà. Il driver del terminale, tuttavia, gestisce ancora caratteri speciali come Control-C e Control-Z, sebbene smetta di gestire caratteri di modifica della riga come backspace o il carattere di cancellazione della parola (in genere Control-W). Inoltre, parte dell'elaborazione dell'output è ancora eseguita, quindi il driver trasforma un \n
in un \r\n
.
In modalità "raw", non viene eseguita alcuna elaborazione né sull'input né sull'output. Nessuna gestione di caratteri speciali, nessuna eco, nessuna trasformazione \n
in \r\n
, nessuna gestione per Control-Z, niente. Sta al programma che mette il terminale in modalità raw per fare tutto.
Ora stai impostando gli attributi per sys.stdin
quindi potresti pensare che questo non dovrebbe influire su sys.stdout
. Ma, in effetti, entrambi i tuoi descrittori di file portano alla stessa identica "istanza" di un driver di terminale. E sono le impostazioni per il driver del terminale che determinano cosa succede. Quindi non importa se modifichi queste impostazioni tramite sys.stdin
, sys.stdout
, o anche sys.stderr
, cambiano tutti la stessa istanza del driver di terminale sottostante e influenzano tutti gli altri.
Questo, ovviamente, non è vero per i descrittori di file che sono stati reindirizzati dalla shell prima dell'avvio del programma.
Come nota a margine, puoi usare il stty -a
sulla riga di comando per vedere una lettura completa di tutti questi flag (inclusi quali caratteri di controllo risultano in quali segnali nelle modalità cotte e cbreak).
Google mi ha portato qui quando stavo cercando una risposta a questa stessa domanda. L'indizio condiviso da Halex sul mancato ritorno a capo ha aiutato la mia ricerca della verità. Ho trovato le mie risposte in un post sul Wiki di Chris:https://utcc.utoronto.ca/~cks/space/blog/unix/CBreakAndRaw che mi ha portato a leggere la fonte di tty.py qui:https://hg. python.org/cpython/file/618ea5612e83/Lib/tty.py Il che mi ha portato alla conclusione che se l'obiettivo è leggere singoli caratteri, invece di:
tty.setraw()
Usa:
tty.setcbreak()