有什么原因导致我在控制台登录屏幕上按下^ [[A的情况?


32

每当我在控制台登录时,我都会up有意按箭头以查看先前键入的命令。但是我看到了^[[A

但是当我按下Ctrl Alt Print Screen Scroll Lock Pause Break Page Up Page Down Win按键时,不会回显任何字符。

可能是什么原因?

是否^[[A有点字符意味着什么?

在此处输入图片说明

Answers:


20

这就是终端代表键盘发送给它的Up键的原始键代码的方式。基本上,您的外壳通常会拦截按键,但是在登录提示符下没有任何操作。因此,您键入的字符会像其他任何字母(或数字或其他字符)一样被打印到控制台。


3
@RubanSavvy Ctrl,Alt和Win(在GNU / Linux世界中通常称为Super)是修饰符。如果按它们和一个键,则会在屏幕上看到不同的内容。尽管我不确定,但我怀疑滚动锁定是由内核或其他较低级别的(对于tty控制)解释的。向上或向下翻页可能会被getty或吞下login,尽管我不确定为什么。有根据的猜测说,出于历史原因,内核专门解释了打印屏幕。但是,除修饰符外,我不确定100%可以使用。
奋斗

3
以上内容可能应该编辑为答案。
奋斗


19

键盘将事件发送到计算机。一个事件说“扫描码nnn向下”或“扫描码nnn向上”。在链的另一端,在终端中运行的应用程序期望以字符序列的形式输入。(除非他们像X服务器一样要求原始访问。)按时A,键盘将发送信息“向下扫描代码38”。控制台驱动程序查找其键映射,并将其转换为“字符a”(如果未按下任何修改键)。

当您按下不产生字符的键或组合键时,信息需要按照字符进行编码。一些键和组合键具有相应的控制字符,例如Ctrl+ A发送字符(字节值1),Return发送字符(Ctrl + M,字节值13)等。大多数功能键没有相应的字符,而是发送以(转义,字节值27)字符开头的字符序列。例如,将密钥Up转换为转义序列␛[A(三个字符:转义,大括号,大写A)。

控制台上的用户名提示很傻,无法理解大多数转义序列。它没有您习惯的线路版本和历史记录功能:这些功能由Shell提供,并且在您登录之前,您没有外壳程序。因此,它只是显示转义序列。字符没有字形,因此显示为^[^传统上,该符号用作控制字符的前缀,而转义则是^[由于其字节值:它是的字节值[减64。

如果Up在shell提示符下按,这会将相同的3个字符的序列发送到您的shell。Shell将其解释为命令序列(通常是调用先前的历史记录项)。如果在外壳程序提示符处按Ctrl+ 键,V则会Up在提示符处插入转义序列:Ctrl+ V是用于按字面意义插入下一个字符的命令,而不是将其解释为命令,因此该字符不会被解释为转义序列的开始。

一些键只是修饰符,不会传输到终端应用程序。例如,当您按时Shift,此信息保留在终端驱动程序中,如果您再按A,则将其考虑在内,因此驱动程序将A代替发送至应用程序a

此外,某些功能键可能未在您的控制台中映射。

对于GUI中的类似视图,请参阅什么是bash的meta键?


一如既往地感谢吉尔斯,这是一个很好的答案。
JoshuaRLi

5

这与“终端”(即终端仿真器应用程序)如何表示键无关。您将看到的是用于向上移动一行但转换为可打印形式的ANSI代码(ANSI转义序列)。

  1. 键盘硬件发送“扫描代码”,但是它们会被翻译并作为字符显示给命令行级应用程序。该键A变成一个字节:A如果Shift键按下(或Shift键锁定),a否则。

  2. 在符合ANSI的终端中,箭头键不会发送单个字符(ASCII字符集中没有用于箭头的代码),而是三个字符的“转义序列”:escape-[-A。其他三个箭头键是escape-[-B, C, D

  3. 如果将相同的字符序列发送(回送)到旧的物理ANSI终端,则会使光标向上移动一行。许多程序,包括终端仿真器,都可以识别这些字符序列并执行适当的操作:终端仿真器将使光标向上移动(这是curses库向四周移动光标的方式),但是bash会拦截它并滚动历史记录。

  4. 为了避免在没有用光标在屏幕上移动的程序中将光标停在各处,您经常会在键盘输入中看到ESC显示为可打印序列^[(因为转义对应于control-[)。这实际上是由终端设备接口处理的;见stty(1)。结果,向上箭头将显示为^[[A。如果键入cat,请按回车,然后按一些箭头键,您将在命令行中看到此内容。这也是您在控制台登录屏幕上看到的。

最后:ControlAlt和您提到的其他键不会映射到字符序列。它们会影响另一个按键发送的字符(如上面的a/ A示例),或者它们根本没有映射到文本。此类按键只能由侦听键盘事件的程序检测到。通过从标准输入读取(或将其写入文件)无法看到它们。


3

这种行为因外壳而异。大多数Shell使用称为的库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可以在其中清空)


5
您的答案是另一回事,因为登录提示是由打印和处理的login,与无关bash
Risto Salminen

1
bashlogin使用相同的库(readline)来编辑行。不同之处在于,login它不会像将垂直箭头键一样解释为命令bash
混乱

是的,我承认。
Risto Salminen

bash语法看起来像是的^[表示形式escape,但是它们是不同的东西。Bash完全可以使用任何语法。实际上,当您编写时\[A,bash输出三个字符:(^[即转义)[,,A
Alexis

0

这些是ANSI转义码^[是Shell用于显示ESC字节(ASCII字节27)的表示法。因此,您的示例是一个ESC字节,后跟文本[A。如您在Wikipedia文章中所见,^[[ESC后跟[)是一个Control Sequence Introducer或CSI。CSI A表示将光标向上移动一列。

如果要在终端中看到转义码,请键入CTRL + V,然后键入另一个键序列。例如,按CTRL + V,然后显示向上箭头^[[A


0

命令外壳(例如Bash)是将箭头向上转换为动作“检索上一命令”的程序。您没有运行命令外壳。


0

TLDR

您可能正在运行sh,它输出按向上箭头键时生成的原始键码。

诸如此类的更高级的shell会bash拦截这些键码并对其进行处理。例如,显示历史记录中的最后一条命令。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.