Есть ли причина, по которой я получаю ^ [[A, когда нажимаю стрелку вверх на экране входа в консоль?


32

Всякий раз, когда я нахожусь в консоли входа в систему, я upнамеренно нажимаю стрелку, чтобы увидеть ранее набранные команды. Но я вижу это ^[[A.

Но когда я нажимаю Ctrl Alt Print Screen Scroll Lock Pause Break Page Up Page Down Winклавиши, не отображаются символы.

В чем может быть причина?

Разве ^[[Aсимволы подразумевают что-нибудь?

введите описание изображения здесь

Ответы:


20

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


3
@RubanSavvy Ctrl, Alt и Win (часто называемые Super в мире GNU / Linux) являются модификаторами. Если вы нажмете их и клавишу, вы увидите что-то другое, напечатанное на экране. Блокировка прокрутки, я подозреваю, интерпретируется ядром или чем-то другим, низким уровнем, для контроля tty, хотя я не уверен. Страница вверх и вниз, вероятно, проглочена gettyили login, хотя я не знаю почему. Образованное гадание говорит, что экран печати интерпретируется специально ядром по историческим причинам. Я не уверен на 100% ни в одном, кроме модификаторов.
стружка

3
Выше, вероятно, следует отредактировать в ответ.
стружка

Связанное обсуждение в чате: chat.stackexchange.com/transcript/message/12481097#12481097
Strugee

19

Клавиатуры отправляют события на компьютер. Событие говорит «сканировать код nnn вниз» или «сканировать код nnn вверх». На другом конце цепочки приложения, работающие в терминале, ожидают ввода в виде последовательности символов. (Если они не запросили необработанный доступ, как это делает X-сервер.) Когда вы нажимаете A, клавиатура отправляет информацию «отсканировать код 38 вниз». Драйвер консоли ищет свою раскладку клавиш и преобразует ее в «символ a» (если не нажата клавиша-модификатор).

Когда вы нажимаете клавишу или комбинацию клавиш, которая не приводит к символу, информация должна быть закодирована в виде символов. Некоторые клавиши и комбинации клавиш имеют соответствующие управляющие символы, например, Ctrl+ Aотправляет символ (значение байта 1), Returnотправляет символ (Ctrl + M, значение байта 13) и т. Д. Большинство функциональных клавиш не имеют соответствующего символа и вместо этого отправляют последовательность символов, начинающаяся с символа (escape, значение байта 27). Например, ключ Upпереводится в escape-последовательность ␛[A(три символа: escape, открывающая скобка, заглавная A).

Запрос имени пользователя на консоли тупой и не понимает большинство escape-последовательностей. Он не имеет функций линейного издания и истории, к которым вы привыкли: они предоставляются оболочкой, и до входа в систему у вас нет оболочки. Так что он просто отображает escape-последовательность. Для персонажа нет символа , поэтому он отображается как ^[. ^Знак традиционно используется в качестве префикса для управляющих символов, и побег ^[из его байт значения: это значение байта [, минус 64.

Если вы нажмете Upна приглашение оболочки, это отправит ту же 3-символьную последовательность в вашу оболочку. Оболочка интерпретирует это как последовательность команд (обычно для вызова предыдущего элемента истории). Если вы нажмете Ctrl+ Vзатем Upв приглашении оболочки, это вставит escape-последовательность в приглашении: Ctrl+ V- это команда, которая вставляет следующий символ буквально вместо того, чтобы интерпретировать его как команду, поэтому символ не интерпретируется как начало escape-последовательности ,

Некоторые ключи являются только модификаторами и не передаются в терминальные приложения. Например, когда вы нажимаете Shift, эта информация остается в драйвере терминала и учитывается, если вы затем нажимаете A, поэтому драйвер отправляет Aв приложение вместо a.

Кроме того, некоторые функциональные клавиши могут не отображаться в вашей консоли.

Для аналогичного представления в графическом интерфейсе см. Что такое мета-ключ bash?


Это отличный ответ, спасибо Жилю как всегда.
JoshuaRLi

5

Дело не в том, как ключи представлены «терминалом» (т. Е. Приложением эмулятора терминала). То, что вы видите, это код ANSI ( escape-последовательность ANSI ) для перемещения вверх на одну строку, но переведенный в печатную форму.

  1. Аппаратное обеспечение клавиатуры отправляет «коды сканирования», но они переводятся и представляются приложениям уровня командной строки в виде символов. Ключ Aстановится одним байтом: Aесли клавиша Shift нажата (или Shift Lock), в aпротивном случае.

  2. В ANSI-совместимый терминал, клавиши со стрелками , не отправить одного символа (там нет кодов для стрелок в наборе символов ASCII), а 3-символьный «последовательность»: escape-[-A. Остальные три клавиши со стрелками escape-[-B, C, D.

  3. Та же последовательность символов будет перемещать курсор вверх на одну строку, если она отправляется (выводится эхом) на старый физический терминал ANSI. Многие программы, включая эмуляторы терминалов, распознают эти последовательности символов и делают что-то подходящее: эмуляторы терминалов будут перемещать курсор вверх (именно так cursesбиблиотека перемещает курсор вокруг), но bashперехватывают его и вместо этого прокручивают историю.

  4. Во избежание того, что курсор окажется в любом месте в программах, которые бесполезны для перемещения курсора по экрану, вы часто будете видеть ESC при вводе с клавиатуры в виде последовательности для печати ^[(потому что escape соответствует control-[). Это фактически обрабатывается интерфейсом оконечного устройства; см stty(1). В результате стрелка вверх будет отображаться как ^[[A. Вы увидите это из командной строки, если вы наберете cat, нажмете клавишу return и нажмете несколько клавиш со стрелками. Это также то, что вы видели на экране входа в консоль.

Наконец: Control, Alt, и другие ключи вы упомянули , не отображаются в последовательности символов. Они влияют на символ, отправляемый другим нажатием клавиши (например, a/ Aпример выше), или они просто не имеют привязки к тексту. Такие нажатия клавиш могут быть обнаружены только программами, которые прослушивают события клавиатуры. Их нельзя увидеть при чтении из стандартного ввода (или записать в файл).


3

Это поведение отличается от оболочки к оболочке. Большинство оболочек используют библиотеку, вызываемую readlineдля редактирования строк в приглашении. Вот полный справочник команд для этой библиотеки, поэтому при использовании приложения readlineвы можете редактировать и перемещаться по строкам с помощью этих команд.

Клавиши вертикальной стрелки настроены в readline для навигации по истории команд. И в приглашении входа нет истории команд. Именно поэтому символы ^[[Aи ^[[Bнапечатаны на экране. Так что же ^[[Aзначит?

Страница руководства bash гласит PROMPTING:

\[     begin a sequence of non-printing characters, which could be used to embed
       a terminal control sequence into the prompt

Эти управляющие последовательности для клавиш со стрелками в ANSI являются:

  • [ValueAКурсор вверх (где Valueможно емтпы)

  • [ValueBКурсор вниз (где Valueможет быть emtpy)


5
Ваш ответ о другом, потому что приглашение для входа в систему распечатывается и обрабатывается login, что не имеет отношения к bash.
Ристо Салминен

1
bashи loginиспользуют одну и ту же библиотеку (readline) для редактирования строк. Разница лишь в том, loginчто не интерпретируйте вертикальные клавиши со стрелками как команду, как это bashделает.
хаос

Да, я признаю это.
Ристо Салминен

Синтаксис bash должен выглядеть как ^[представление escape, но это разные вещи. Bash мог бы использовать любой синтаксис вообще. В самом деле, когда вы пишете \[A, баш выдает три символа: ^[(т.е. побег), [, A.
Алексис

0

Это аварийные коды ANSI . ^[это нотация, используемая вашей оболочкой для отображения ESCбайта (байт ASCII 27). Итак, ваш пример - байт ESC, за которым следует текст [A. Как вы можете видеть в статье в Википедии, ^[[( ESCсопровождаемой [) является Представитель контрольной последовательности или CSI. CSI Aозначает переместить курсор вверх на один столбец.

Если вы хотите увидеть управляющий код в терминале, введите CTRL + V, а затем другую последовательность клавиш. Например, CTRL + V и стрелка вверх показывают ^[[A.


0

Командная оболочка, например Bash - это программа, которая переводит стрелку вверх в действие «восстановить предыдущую команду». У вас не работает командная оболочка.


0

TLDR

Вы, вероятно, работаете, shкоторый выводит необработанные коды клавиш, генерируемые при нажатии клавиши со стрелкой вверх.

Более продвинутая оболочка, например, bashперехватывает эти коды клавиш и что-то с ними делает. Например, показать последнюю команду в своей истории.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.