Почему {} стал отображаться как äå в Terminal.app?

Чистый ответ bash

echo "0 hello world the man is world
1 this is the world
2 a different man is the possible one" | while IFS=$'\n' read -r line; do echo $line | tr ' ' '\n' | sort -u; done | sort | uniq -c


   1 0
   1 1
   1 2
   1 a
   1 different
   1 hello
   3 is
   2 man
   1 one
   1 possible
   3 the
   1 this
   2 world

Я зациклил уникальные слова в каждой строке и передал ихuniq -c

редактировать :Я не видел ответа Гленна. Мне показалось странным не увидеть ответ bash

17
08.03.2021, 15:41
1 ответ

Я могу воспроизвести это с помощью xtermэмулятора терминала (версии 366 ), если я это сделаю:

$ printf '\e[?42h\e(H'; cat chars.txt; printf '\e(B\e[?42l'
!É#$%Ü&*()_+äå

Где:

Другие отменяют настройки.

Чтобы вернуть терминал в нормальное состояние, вы также можете использовать команду ncurses reset. Здесь я обнаружил, что это последовательность \ec, которую он отправляет возможности(rs1/ reset_1string, отправленные tput rs1, например ), которые заботятся о восстановлении наборов символов по умолчанию ).

Что касается того, почему nano, например, отображает их нормально, вы обнаружите, что если вы запустите nanoвнутри командного сеанса scriptи посмотрите результат typescriptпосле этого, nanoдействительно отправляет \e(Bпоследовательность (выбирает US -ASCII для G0 )после переключения на альтернативный экран с \e[?1049hпредположительно как часть некоторой инициализации ncurses, и исходная кодировка восстанавливается, когда nanoпокидает этот альтернативный экран при выходе.

Теперь получение последовательности \e(H(0x1b 0x28 0x48 байтовой последовательности )в двоичном файле случайно. В среднем одна из 16 миллионов случайных 3-байтовых последовательностей является именно такой. Здесь я нахожу некоторые в:

$ LC_ALL=C grep -rFl $'\e(H' /lib
/lib/x86_64-linux-gnu/libicui18n.so.66.1
/lib/x86_64-linux-gnu/ceph/libceph-common.so.2
[...]

, например.

Но найти \e[?42h, 6-байтовую (48-битную )последовательность случайно было бы намного более маловероятным (1 из 280 триллионов 6 -байтовых последовательностей ). И уж тем более иметь и это, и \e(Hв таком порядке в случайном бинарном файле, который вы сбрасывали на терминал.

Но xtermна CentOS7 — это старая версия (295 ). И в этой версии последовательность \e[?42hдля включения этой обработки ISO2022 не требуется. В этой версии xterm, \e(Hдостаточно для получения такого поведения. Это изменилось в версии 297 , выпущенной в сентябре 2013 года.Это объясняет, почему это чаще встречается в CentOS7 или любой системе той эпохи, чем в более поздних системах.

Поскольку вы указали, что ваша рабочая станция работает под управлением macos, а не CentOS, обратите внимание, что macos, похоже, поставляется с еще более старой версиейxterm(269по состоянию на 2021 год ), и я ожидаю, что эмулятор терминала Terminal.app, который вы уточнили вы на самом деле использовали ту же ошибку, что и xtermдля (в том, что он не эмулировал терминал VT220 должным образом, хотя, возможно, его целью было эмулировать эти старые версии xtermвместо ).

В еще более старые времена (вплоть до xterm 182 , где он был изменен, я полагаю, ), другим распространенным артефактом при сбросе двоичных файлов на терминал было переключение на специальный символ и Рисование линии Установите , когда на терминал был отправлен байт 0x0e(SO/ ^Nуправляющий символ ). SOпо-прежнему переключается на набор G1, но в то время, когда набор G1 был инициализирован как набор рисования линий . Вы получите тот же эффект сегодня (, хотя менее вероятно, что он произойдет из случайного двоичного кода ), отправив последовательность \e(0, которая выбирает набор рисования линий для G0 :

.
$ printf '\e(0 blahblah \e(B\n'
 ␉┌▒␤␉┌▒␤

Вы можете вернуться к старому поведению, когда ^N/ ^Oпереключаются между ASCII и набором рисунков с помощью последовательности \e)0.

Что касается того, почему перезагрузка не помогла, имейте в виду, что эта управляющая последовательность повлияла на ваш эмулятор терминала. Перезагрузка системы, в которую вы вошли sshс этого эмулятора терминала, не поможет. Перезагрузка системы, на которой вы запустили xterm, могла бы помочь, но также был бы перезапуск только этого эмулятора терминала или запуск этой команды reset, как показано выше, в терминале (локально или через ssh, это не помогает. Не имеет значения, пока на эмулятор терминала )отправляется управляющая последовательность rs1.

Подробнее на:

60
18.03.2021, 22:27

Теги

Похожие вопросы