Альтернативные наборы символов в эмуляции терминала

Альтернативные наборы символов в эмуляции терминала

Иногда я случайно загружаю catнекоторые двоичные данные; иногда какая-то программа ncurses вылетает - по многим причинам терминал может оказаться в плохом состоянии, требующем ручного вмешательства reset. Это происходит слишком часто.

Таким плохим состоянием может быть отсутствие эха, или превращение всего в китайский мусор, или многое другое.

Есть ли простой способ убедиться, что настройки терминала (без жесткого сброса, очистки экрана и т. д.) будут восстановлены, когда shell восстановит управление?

Это bashтак, Terminal.appно я полагаю, что эта проблема носит практически универсальный характер.

решение1

Проблемы, о которых вы говорите, возникают на разных уровнях, и только некоторые из них можно решить с помощью «кодов управления».

Альтернативные наборы символов в эмуляции терминала

Существует распространенная проблема терминала, которую можно описать так: «(некоторые) строчные буквы отображаются как символы или знаки рисования линий» (см.этот другой вопрос ТАК). Это может быть не связано с вашей проблемой «китайского мусора», но это самое близкое, что я видел. Вы также можете столкнуться с «китайским мусором» при интерпретации почти любого 8-битного потока данных как текста в кодировке UTF-16. Обычно это не «липкая» проблема, которую нужно сбросить, так что, вероятно, это не та проблема, которую вы видите.

Проблема «застревания символов рисования линий» обычно возникает из-за отправки эмулятору терминала непреднамеренной управляющей последовательности (или остановки программы до того, как она сбросит терминал после переключения на альтернативный набор символов). Это может произойти, когда отображаются некоторые двоичные данные, а поток байтов содержит управляющую последовательность терминала, которая выбирает альтернативный набор символов.

Это легко осуществить на большинстве терминалов типа VT-100, поскольку для этого требуется всего один байт (0x0e; см.мой ответ на ранее связанный вопрос SO). Управляющая последовательность для сброса этого состояния также представляет собой один байт (0x0f; часто создается через echo ^V^O(набирается как echo Control+ V Control+ Oили напрямую набирается как printf '\017').

Вы можете устранить эту проблему , ** добавив в приглашение байт 0x0f.
**Если ваш «китайский мусор» вызван какой-то другой проблемой, то у нее может быть другое решение.

PS1="\[\017\]… "

И \[они \]там, чтобы рассказатьБашчто ограниченный символ непечатаемый. Это позволяетБашсохраняйте точное представление о «физическом» положении курсора (это важно для правильного повторного отображения при использовании функции редактирования командной строки).


Как отмечает Игнасио Васкес-Абрамс вего ответ, другой способ получить желаемую последовательность управления — черезtputкоманда:

tput rmacs

Используя этот метод, вы можете избежать изменения PS1 и просто поместить указанную выше команду в PROMPT_COMMAND:

PROMPT_COMMAND='tput rmacs'

Параметры TTY (termios)

Проблема «нет эха» *** возникает из-за неожиданных настроек параметров для устройства tty на базе ОС, которое подключает ваш эмулятор терминала ко всем программам, работающим внутри окна терминала. Это часто вызвано программами интерактивного текстового пользовательского интерфейса, которые имеют ошибки, аварийно завершаются или завершаются, так что они не могут восстановить tty в исходное состояние.

Вы можете управлять этими настройками с помощьюsttyкоманда. Этот тип проблемы не может быть решен с помощью «кодов управления», поскольку параметры tty настраиваются через программные API (см.tcsetattr(3)итермины(4)). В целом stty saneэто хороший механизм сброса.
*** Также «нет ^C/^Z/^/», «ступенчатый вывод» (нет автоматического CR при получении LF) и несколько других проблем.

перезагрузить

TheперезагрузитьКоманда обычно может помочь с обоими типами проблем. Она отправит последовательности управления инициализацией терминала, которые обычно исправляют проблему с альтернативным набором символов, и сбрасывает параметры tty до разумных значений.

Проблема сперезагрузитьзаключается в том, что он также выводит дополнительные сообщения на некоторых системах (например, «Стирание — это…», «Прерывание — это…»); вы, вероятно, не хотите, чтобы они отображались перед каждым запросом. Если ваша реализацияперезагрузитьотправляет сообщения и управляющие последовательности в разные места (например, одно отправляется на stdout, а другое — на stderr), тогда вы можете отфильтровать сообщения (например, PROMPT_COMMAND='reset 2>/dev/null'(см. ниже) и пропустить ввод ^O в приглашение).

^О иstty sane

ВБаш, вы можете установить параметр PROMPT_COMMANDдля команды иБашзапустится, если перед отображением основного приглашения. Вы можете поместить все вызовы stty saneтуда и вставить ^O в свое приглашение:

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

Опять же, вы можете избежать модификации PS1 (и работать с терминалами, отличными от VT-100), используяtput(как предложил Игнасио Васкес-Абрамс):

PROMPT_COMMAND='stty sane; tput rmacs'

решение2

Помещать

echo -n "$(tput rmacs)"

в $PROMPT_COMMAND.

решение3

Так что я буду меньше командной строки, у вас всегда есть в xterm или в любом терминале "кнопка" сброса или жесткого сброса, для terminal.app она находится в меню Shell. Отправить Жесткий сброс alt-command-r.

Связанный контент