Sieht so aus, als würdest du nur einen Zeilenvorschub machen, aber keinen Wagenrücklauf. Ändern Sie Ihren Ausdruck in
print("ASD", end="\r\n")
Das Problem, das Sie haben, ist der Unterschied zwischen den Modi „roh“, „gekocht“ und „cbreak“. Und diese Modi sind Modi des Terminaltreibers auf Kernelebene, keine Modi Ihres Anwendungscodes oder der Standardbibliothek oder irgendetwas anderem im Benutzerbereich. Dies ist die Unix-Art der alten Schule, sich auf diese zu beziehen. Posix hat sie durch einen viel feinkörnigeren Satz von Attributen ersetzt, obwohl die Posix-Attribute typischerweise zusammen mit Hilfsfunktionen auf eine Weise umgedreht werden, die die alten Modi „roh“, „gekocht“ und „cbreak“ nachahmt.
Im Cooked-Modus verfügt der Terminaltreiber selbst über eine eingebaute einfache Zeilenbearbeitungsfunktion. Es behandelt Backspace, Wortlöschung (im Grunde ein ganzes Wort auf einmal) und ähnliche Dinge. Nichts so anspruchsvolles wie der Umgang mit Pfeiltasten oder Geschichte oder so etwas. Sehr primitiv. In diesem Modus sieht Ihr Programm nie etwas vom Terminal, bis das Zeilenendezeichen (eol) gesendet wird, und dann erhält Ihr Programm eine ganze Zeile, und das Zeilenende wird in den Unix-Standard \n
unabhängig davon, was das Terminal tatsächlich tut. Als Teil davon gibt der Terminaltreiber auch eingegebene Zeichen an das Terminal zurück, damit der Benutzer sehen kann, was er eingibt.
Im 'Cooked'-Modus führt der Terminaltreiber auf Kernel-Ebene auch einige Ausgabeübersetzungen durch. Und ein Teil davon wird \n
in \r\n
bei Bedarf.
Außerdem behandelt der Terminaltreiber im „Cooked“-Modus Sonderzeichen wie Control-C (sendet ein SIGINT an die steuernde Prozessgruppe (übersetzt von CPython in eine KeyboardInterrupt-Ausnahme)) und Control-Z (sendet ein SIGTSTP (wie ein SIGSTOP, aber abgefangen werden können) an die steuernde Prozessgruppe).
Im 'cbreak'-Modus wird die Zeilenbearbeitung nicht mehr durchgeführt. Der Terminaltreiber gibt jedes Zeichen (oder kurze Zeichenfolge, wie die Escape-Sequenz für eine Pfeiltaste) sofort an das Programm weiter. Diese Zeichen werden nicht auf dem Bildschirm wiedergegeben, und der Benutzer wird sie daher nicht sehen, es sei denn, Ihr Programm gibt sie dann aus. Der Terminaltreiber verarbeitet jedoch immer noch Sonderzeichen wie Strg-C und Strg-Z, obwohl er aufhört, Zeilenbearbeitungszeichen wie die Rücktaste oder das Wortlöschzeichen (normalerweise Strg-W) zu verarbeiten. Außerdem wird noch ein Teil der Ausgabeverarbeitung durchgeführt, sodass der Treiber eine \n
ändert in \r\n
.
Im „Raw“-Modus erfolgt weder am Eingang noch am Ausgang eine Verarbeitung. Keine Behandlung von Sonderzeichen, kein Echo, kein Transformieren von \n
in \r\n
, keine Handhabung für Control-Z, nichts. Es liegt an dem Programm, das das Terminal in den Raw-Modus versetzt, um alles zu erledigen.
Jetzt setzen Sie die Attribute für sys.stdin
Sie denken also vielleicht, dass dies sys.stdout
nicht beeinflussen sollte . Aber tatsächlich führen beide Ihrer Dateideskriptoren zu genau derselben 'Instanz' eines Terminaltreibers. Und es sind die Einstellungen für den Terminaltreiber, die bestimmen, was passiert. Es spielt also keine Rolle, ob Sie diese Einstellungen über sys.stdin
ändern , sys.stdout
, oder sogar sys.stderr
, ändern alle dieselbe zugrunde liegende Terminaltreiberinstanz und wirken sich auf alle anderen aus.
Dies gilt natürlich nicht für Dateideskriptoren, die von der Shell umgeleitet wurden, bevor Ihr Programm gestartet wurde.
Als Randnotiz können Sie den stty -a
verwenden auf der Befehlszeile, um eine vollständige Anzeige all dieser Flags zu sehen (einschließlich der Steuerzeichen, die zu welchen Signalen im Cooked- und Cbreak-Modus führen).
Das Google brachte mich hierher, als ich nach einer Antwort auf dieselbe Frage suchte. Der von Halex geteilte Hinweis von No Carriage Return half meiner Suche nach der Wahrheit. Ich habe meine Antworten in einem Beitrag im Wiki von Chris gefunden:https://utcc.utoronto.ca/~cks/space/blog/unix/CBreakAndRaw, was mich dazu veranlasst hat, die Quelle von tty.py hier zu lesen:https://hg. python.org/cpython/file/618ea5612e83/Lib/tty.pyWas mich zu dem Schluss brachte, dass, wenn das Ziel darin besteht, einzelne Zeichen zu lesen, statt:
tty.setraw()
Verwendung:
tty.setcbreak()