GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Python im Raw-Modus stdin print fügt Leerzeichen hinzu

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()

Linux
  1. Mac Terminal vi[m] Editor-Befehle

  2. Pseudo-Terminal wird nicht zugewiesen, da stdin kein Terminal ist

  3. Python-Raw-Socket:Protokoll wird nicht unterstützt

  4. Raw-Socket in Python ohne Root-Rechte erstellen

  5. Python lesen mit dem Namen PIPE

Drucken Sie Dateien von Ihrem Linux-Terminal aus

Drucken Sie die neuesten Weltraumereignisse mit Nextinspace im Terminal

Konvertieren Sie Tabulatoren in Leerzeichen im Linux-Terminal mit dem Befehl „Erweitern“.

Wie führe ich ein Python-Skript auf dem Terminal (Ubuntu) aus?

Wie beendet man das Linux-Terminal mit einem Python-Skript?

Wie kann man stdin vom Terminal aus plotten?