Проблемы, которые вы упоминаете, возникают в разных слоях, и только некоторые из них могут быть решены с помощью «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'