Как узнать, какая комбинация клавиш представлена ​​определенной последовательностью символов

Утилита raid6checkиз mdadmвключает режим repairначиная с версии 3.3 (выпущенной в 2013 году -09 -03)(точнее с момента этого коммита:https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git/commit/?id=8a63c73123b9d022107c82bd684e17bf87bc081e)

1
29.07.2020, 13:17
4 ответа

Пока ваш терминал генерирует последовательности управления вводом в форме ECMA -48 или в формах DECFNK, Interix, SCO Console или Unicode RXVT, вы можете передать их моему инструменту console-decode-ecma48с помощью --inputОпция строки command -, чтобы указать, что поток символов является вводом, а не выводом. Это справедливо для большинства терминалов и эмуляторов терминалов, с которыми вы сегодня столкнетесь на практике.

Вот что он делает с вашим вводом, с заменой ^[фактическим символом , конечно:

% console-decode-ecma48 --input << EOF
^[^?
^X^U
^[[3;5~
^[[1;2D
^[[1;2C
^[[1;5C
^[[1;5D
^[[1;6C
^[[1;6D
EOF
DEL
LF
U+00000015
LF
DEC Control+DELETE
LF
Level2+CUB 1
LF
Level2+CUF 1
LF
Control+CUF 1
LF
Control+CUB 1
LF
Control+Level2+CUF 1
LF
Control+Level2+CUB 1
LF
%

Как отмечено в https://unix.stackexchange.com/a/504056/5132, если вы хотите расшифровать то, что некоторые терминалы делают с клавишными аккордами ⎇ Alt , вам также потребуется опция --no-7bit; в противном случае вы получите стандартное декодирование ECMA -48 7-битных псевдонимов -для управляющих символов C1.

CUFи CUBявляются стандартными ECMA -48 имен, конечно :"CU rsor F вперед" и "CU rsor B назад". См. руководство.

Правила для последовательностей управления терминалом могут вас удивить. Вы набрали , DEL, , и . Правила для последовательностей управления терминалом обрабатывают это следующим образом:

  1. начинает управляющую последовательность.
  2. DEL обрабатывается немедленно как управляющий символ, оставляя управляющую последовательность все еще отложенной.
  3. обрабатывается немедленно как управляющий символ, оставляя управляющую последовательность все еще отложенной.
  4. отменяет (нахождение в имени )ожидающей escape-последовательности.
  5. обрабатывается как управляющий символ C0. console-decode-ecma48печатает свою кодовую точку Unicode в случае этого конкретного символа.

Обратите внимание, что ни одна из известных мне оболочек на самом деле не содержит правильный декодер ECMA -48. Оболочки выполняют сопоставление с образцом, что значительно несовершенно при обработке фактических данных, закодированных в соответствии с ECMA -48, которые терминалы отправляли все это время. Это приводит к таким вещам, как проблемы, обсуждавшиеся вhttps://unix.stackexchange.com/a/499139/5132иhttps://unix.stackexchange.com/a/520429/5132среди многих других.

console-decode-ecma48на самом деле имеет надлежащий декодер ECMA -48 с конечным автоматом управляющей последовательности, с вариантами для консоли SCO, Interix и так далее. Он не покажет вам в точности , что сделают с вашим вводом такие вещи, как GNU Readline, libedit и ZLE, потому что они неправильно понимают протокол.

Но он покажет то, что терминал ECMA -48 думал, что он отправляет, что вам здесь и нужно.

Дополнительная литература

  • Джонатан де Бойн Поллард (2018 ). «console-decode-ecma48». Направляющая ноша . Программное обеспечение.
2
20.08.2021, 10:42

баш

$ bind -p | grep -F '[3;5~'
"\e[3;5~": delete-char
0
20.08.2021, 10:42

Первая пара строк

^[^?
^X^U

— это коды, которые вы можете найти в виде таблицы элементов управления ASCII

^[  (escape)
^U  (control-U)
^X  (control-X)

Что^?является обычным представлением ASCII DEL (клавиша удаления ).

Если описание терминала(TERM)установлено правильно,

infocmp -1 -x

напечатает имена ncurses для ключей в формате terminfo. Есть и другая информация, но вы увидите эти строки:

kDC5=\E[3;5~,

kRIT=\E[1;2C,
kRIT3=\E[1;3C,
kRIT4=\E[1;4C,
kRIT5=\E[1;5C,
kRIT6=\E[1;6C,
kRIT7=\E[1;7C,

kLFT=\E[1;2D, 
kLFT3=\E[1;3D,
kLFT4=\E[1;4D,
kLFT5=\E[1;5D,
kLFT6=\E[1;6D,
kLFT7=\E[1;7D,

, который (с учетом того, что terminfo\Eявляется escape-кодом ASCII, или ^[), который вы можете распознать как соответствующий вашему примеру. НазванияkLFTиkRITговорят мне, что это (xterm -стиль)модифицированный клавиши курсора влево/вправо (см.XTerm Control Sequencesдля значение цифры после имени в таблице кодов/модификаторов ).Имена terminfo перечислены в базе данных терминала :

.
# These are the extended keys defined in this file:
#
# kDC3 kDC4 kDC5 kDC6 kDC7 kDN kDN3 kDN4 kDN5 kDN6 kDN7 kEND3 kEND4 kEND5 kEND6
# kEND7 kHOM3 kHOM4 kHOM5 kHOM6 kHOM7 kIC3 kIC4 kIC5 kIC6 kIC7 kLFT3 kLFT4
# kLFT5 kLFT6 kLFT7 kNXT3 kNXT4 kNXT5 kNXT6 kNXT7 kPRV3 kPRV4 kPRV5 kPRV6 kPRV7
# kRIT3 kRIT4 kRIT5 kRIT6 kRIT7 kUP kUP3 kUP4 kUP5 kUP6 kUP7 ka2 kb1 kb3 kc2

и описаны на странице руководства user_caps.

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

Некоторые терминалы отправят это ^[^?, если вы нажмете AltDelete (, но этого нет в описании терминала ). ^X^Uне является последовательностью, отправляемой одной клавишей в эмуляторе терминала (, если только у вас нет переназначенных клавиш ):, более вероятно, что это два нажатия клавиш.

3
20.08.2021, 10:42

Какой символ или последовательность символов отправляет терминал при нажатии одной из его клавиш (или комбинаций клавиш ), зависит от самого терминала.

В то время как aявляется квази -универсальным, что посылают все терминалы, когда вы нажимаете их A клавишу (для тех, у кого есть такая клавиша по крайней мере ), для клавиш типа Home , Left , F1 или Ctrl + 6 и т. д., это сильно различается между терминалами.

Однако есть и кое-что общее. Управляющие символы ASCII со значениями от 0 до 31 часто представляются как ^@, ^A... ^Z, ^[, ^\, ], ^^и ^_. Вы заметите, что для всех них, если вы переключите 6-й бит печатного символа, вы получите соответствующий управляющий символ (, например A— 0x41, ^A— 0x1 ). ^?— 0x7f, ?— 0x3f.

И терминалы отправляют символ ^X, когда вы нажимаете Ctrl + X .

^I— управляющий символ TAB, и этот символ также отправляется при нажатии клавиши Tab для тех, у кого есть (в дополнение к Ctrl + Я).

То же самое для ^[, она же \eи клавиши Esc .

^Hака \bявляется символом возврата, но некоторые терминалы отправляютDEL(^?)после Backspace , а некоторые другие отправляют ^H.

^M, также известный как \r, отправляется при возврате/вводе (, но может быть преобразован в ^J, также известный как \n, драйвером терминального устройства в некоторых режимах ).

^@aka \0можно отправить по Ctrl + @ , но также иногда по Ctrl + Пробел .

Некоторые терминалы имеют клавишу-модификатор Meta или Alt , которая в сочетании с другой клавишей отправляет тот же символ, но с установленным 8-м битом (, например Meta + (без Shift)отправляет байт 0xE1, когда aравен 0x61 ). В то время как некоторые другие (более распространены в наши дни )отправляют символ ^[, за которым следует символ или последовательность символов, которые были бы отправлены без Meta (, например Meta + посылает^[a).

Большинство других функциональных клавиш обычно отправляют последовательность символов, которая начинается с^[(ESC ). Единственным исключением является Удалить , который на некоторых терминалах отправляет DEL(^?).

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

Здесь в игру вступает переменная окружения $TERM. Эта переменная устанавливается либо getty, эмуляторами терминала, либо пользователем, чтобы сообщить приложениям, с каким терминалом они общаются. Значение представляет собой короткое имя, предназначенное для однозначной идентификации типа терминала.

Например, современный эмулятор терминала xtermустановит его на xterm-256color.

Затем эти приложения могут запрашивать базу данных описаний терминалов, используя это значение, чтобы узнать о возможностях этого терминала. Такими возможностями могут быть, например, :какая последовательность символов должна быть отправлена ​​на терминал, чтобы включить жирный вывод текста. И еще может быть последовательность символов, которую приложение получит от терминала, когда вы нажмете клавишу Удалить .

Исторически так сложилось,есть две основные базы данных:termcapи terminfo, каждая с набором API для запроса. В настоящее времяterminfo(более продвинутый )преобладает иncurses(поддерживается @ThomasDickey в течение последних нескольких десятилетий )является общей библиотекой, используемой для взаимодействия с ним (также предоставляет termcap интерфейс, использующий тот же бэкэнд ).

Теперь набор возможных возможностей , хранящихся в этой базе данных, зафиксирован. Это описано на справочной странице terminfo(5).

На передней панели клавиш имеется ограниченное количество закрытых клавиш. Это по-прежнему большой список, включая клавиши, о которых большинство из нас никогда не слышали, но он не включает все функциональные клавиши всех возможных терминалов прошлого и будущего. Он охватывает некоторые комбинации клавиш (, в основном Shift + SomeFuncKeys ), но не все возможные комбинации (, например Ctrl + Shift + Вверх).

В системе GNU см.:

 man 5 terminfo | grep -Po '^\s*\Kkey_.*'

для списка.

Теперь, чтобы запросить базу данных terminfoиз оболочки, вncurses:

есть 3 основные команды.
  • toe:список терминалов в базе данных
  • tput:выводит необработанные возможности (, обычно используемые для отправки escape-последовательностей, например tput boldдля запуска полужирного режима ).
  • infocmp:получает полные записи из базы данных или сравнивает их.

Здесь последнее будет полезно, чтобы выяснить, какой из ключей вашего терминала мог отправить данную последовательность.:infocmp -xL1выводит все возможности, известные для терминала, идентификатор которого хранится в $TERM(, поэтому ваш терминал ), 1на строку и с Lи (более описательными )именами возможностей. Так:

$ infocmp -xL1 | grep key_
        key_b2=\EOE,
        key_backspace=\177,
        key_btab=\E[Z,
        key_dc=\E[3~,
        key_down=\EOB,
        key_end=\EOF,
        key_enter=\EOM,
[...]

Дает вам все последовательности для всех известных клавиш¹.

На моем xtermтерминале, там я вижу:

        key_sright=\E[1;2C,
        key_sleft=\E[1;2D,

Например.

Оболочка zshтакже предоставляет возможности текущего терминала в его $terminfoспециальном ассоциативном массиве (в модуле zsh/terminfo, загружаемом автоматически при доступе к этой переменной ). Так что еще один способ получить информацию —:

$ key=$'\e[1;2D'
$ echo ${(k)terminfo[(Re)$key]}
kLFT

(Это короткие названия терминов ).

В базе данных terminfo нет ни одной клавиши, которая отправляет ^[^?для моего терминала, но я получу эту последовательность, если наберу EscCtrl + ? или Ctrl + [? или Alt + Ctrl + ? например.

Возможно, ваш терминал отправляет ^?при Удалить , тогда вы, возможно, получите это также при Мета + Удалить .

^X^Uбудет отправлено на Ctrl + XCtrl + U , я не могу себе представить, чтобы терминалы имели функциональную клавишу, отправляющую это, хотя обратите внимание, что многие эмуляторы терминала позволяют привязать любую последовательность символов к любой клавише или комбинации клавиш.


¹ Существует дополнительное предостережение для многих терминалов, заключающееся в том, что терминал может отправлять разные последовательности для некоторых функциональных клавиш, когда он находится в режиме приложения клавиатуры , а когда нет. Запись terminfo в этом случае описывает последовательности режима приложения клавиатуры . Приложение может перевести терминал в этот режим, отправив последовательность, соответствующую возможности smkx.

2
20.08.2021, 10:42

Теги

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