Alternative Zeichensätze in der Terminalemulation

Alternative Zeichensätze in der Terminalemulation

Manchmal gebe ich versehentlich cateinige Binärdaten ein; manchmal stürzt ein Ncurses-Programm ab – aus vielen Gründen kann das Terminal in einen schlechten Zustand geraten, der eine manuelle Löschung erfordert reset. Das passiert zu oft.

Ein solcher schlechter Zustand kann beispielsweise kein Echo sein oder die Umwandlung von allem in chinesischen Müll oder vieles mehr.

Gibt es eine einfache Möglichkeit, sicherzustellen, dass die Terminaleinstellungen (ohne Kaltstart, Bildschirmreinigung usw.) wiederhergestellt werden, wenn die Shell die Kontrolle wiedererlangt?

Es ist bashund Terminal.app, aber ich würde vermuten, dass dieses Problem ziemlich universell ist.

Antwort1

Die von Ihnen angesprochenen Probleme treten auf unterschiedlichen Ebenen auf und nur einige davon lassen sich mit „Escape-Codes“ lösen.

Alternative Zeichensätze in der Terminalemulation

Es gibt ein häufiges Terminalproblem, das wie folgt beschrieben werden könnte: „(einige) Kleinbuchstaben werden als Symbole oder Strichzeichnungszeichen angezeigt“ (siehediese andere SO-Frage). Dies hat vielleicht nichts mit Ihrem „chinesischen Müll“-Problem zu tun, aber es ist das, was dem am nächsten kommt, was ich gesehen habe. Sie können auch auf „chinesischen Müll“ stoßen, wenn Sie fast jeden 8-Bit-Datenstrom als UTF-16-codierten Text interpretieren. Normalerweise ist dies kein „hartnäckiges“ Problem, das zurückgesetzt werden muss, also ist es wahrscheinlich nicht das Problem, das Sie sehen.

Das Problem „bei Strichzeichnungszeichen hängen bleiben“ entsteht normalerweise dadurch, dass dem Terminalemulator unbeabsichtigt eine Steuersequenz gesendet wird (oder ein Programm gestoppt wird, bevor es das Terminal nach dem Wechsel zum alternativen Zeichensatz zurückgesetzt hat). Dies kann passieren, wenn einige Binärdaten angezeigt werden und der Bytestream eine Terminalsteuersequenz enthält, die einen alternativen Zeichensatz auswählt.

Dies lässt sich auf den meisten VT-100-Terminals einfach auslösen, da nur ein einzelnes Byte (0x0e; siehemeine Antwort auf die zuvor verlinkte SO-Frage). Die Steuersequenz zum Zurücksetzen dieses Zustands besteht ebenfalls aus einem einzelnen Byte (0x0f; wird häufig erzeugt über echo ^V^O(eingegeben als echo Control+ V Control+ Ooder direkt als printf '\017').

Sie könnten diese Art von Problem beheben , ** indem Sie Ihre Eingabeaufforderung so einrichten, dass sie ein 0x0f-Byte enthält.
** Wenn Ihr „chinesischer Müll“ auf ein anderes Problem zurückzuführen ist, kann es möglicherweise eine andere Lösung geben.

PS1="\[\017\]… "

Die \[und \]sind da, um zu erzählenSchlagdass das gebundene Zeichen nicht druckbar ist. Dies ermöglichtSchlagBehalten Sie eine genaue Vorstellung der „physischen“ Cursorposition (dies ist wichtig für die korrekte Neuanzeige bei Verwendung der Befehlszeilenbearbeitungsfunktion).


Wie Ignacio Vazquez-Abrams inseine Antwort, eine andere Möglichkeit, die gewünschte Steuersequenz zu erhalten, ist über dietputBefehl:

tput rmacs

Mit dieser Methode können Sie die Änderung von PS1 vermeiden und einfach den obigen Befehl in PROMPT_COMMAND einfügen:

PROMPT_COMMAND='tput rmacs'

TTY (Termios)-Optionen

Das „Kein Echo“-Problem *** entsteht durch unerwartete Einstellungen der Optionen für das betriebssystembasierte TTY-Gerät, das Ihren Terminalemulator mit allen Programmen verbindet, die im Terminalfenster ausgeführt werden. Dies wird häufig durch interaktive Text-UI-Programme verursacht, die Fehler aufweisen, abstürzen oder beendet werden, sodass sie das TTY nicht in seinen ursprünglichen Zustand zurückversetzen können.

Sie können diese Einstellungen mit demsttyBefehl. Diese Art von Problem kann nicht mit „Escape-Codes“ gelöst werden, da die TTY-Optionen über Software-APIs konfiguriert werden (siehetcsetattr(3)UndBedingungen(4)). Im Allgemeinen stty saneist dies ein guter Reset-Mechanismus.
*** Außerdem „kein ^C/^Z/^/“, „treppenförmige Ausgabe“ (kein automatisches CR, wenn ein LF empfangen wird) und mehrere andere Probleme.

zurücksetzen

DerzurücksetzenDer Befehl kann normalerweise bei beiden Arten von Problemen helfen. Er sendet Steuersequenzen zur Terminalinitialisierung, die normalerweise das Problem mit dem alternativen Zeichensatz beheben, und setzt die TTY-Optionen auf sinnvolle Werte zurück.

Das Problem mitzurücksetzenist, dass es auf einigen Systemen auch zusätzliche Meldungen ausgibt (z. B. „Löschen ist …“, „Unterbrechen ist …“); Sie möchten diese wahrscheinlich nicht vor jeder Eingabeaufforderung angezeigt bekommen. Wenn Ihre Implementierung vonzurücksetzendie Nachrichten und Steuersequenzen an verschiedene Orte sendet (z. B. geht eine an stdout, während die andere an stderr geht), dann können Sie möglicherweise die Nachrichten herausfiltern (z. B. PROMPT_COMMAND='reset 2>/dev/null'(siehe unten)) und das Einfügen von ^O in die Eingabeaufforderung überspringen).

^O undstty sane

InSchlagkönnen Sie den Parameter PROMPT_COMMANDauf command setzen undSchlagführt if aus, bevor die primäre Eingabeaufforderung angezeigt wird. Sie können alle Aufrufe stty sanedort einfügen und ^O in Ihre Eingabeaufforderung eingeben:

PROMPT_COMMAND='stty sane'
PS1="\[\017\]… "

Auch hier können Sie die Modifizierung von PS1 vermeiden (und Terminals, die nicht dem VT-100-Stil entsprechen, handhaben), indem Sietput(wie von Ignacio Vazquez-Abrams vorgeschlagen):

PROMPT_COMMAND='stty sane; tput rmacs'

Antwort2

Setzen

echo -n "$(tput rmacs)"

In $PROMPT_COMMAND.

Antwort3

Ich werde also weniger Befehlszeilen verwenden. In xterm oder jedem Terminal gibt es immer eine Schaltfläche zum Zurücksetzen oder Hard-Reset. Für terminal.app befindet sie sich im Shell-Menü. Senden Sie „Hard-Reset“ mit Alt-Befehl-R.

verwandte Informationen