2

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

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

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

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

3 ответа3

4

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

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

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

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

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

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

PS1="\[\017\]… "

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


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

tput rmacs

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

PROMPT_COMMAND='tput rmacs'

TTY (termios) Опции

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

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

сброс

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

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

^ O и stty sane

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

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

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

PROMPT_COMMAND='stty sane; tput rmacs'
1

Положил

echo -n "$(tput rmacs)"

в $PROMPT_COMMAND .

0

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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .