Answers:
这就是终端代表键盘发送给它的Up键的原始键代码的方式。基本上,您的外壳通常会拦截按键,但是在登录提示符下没有任何操作。因此,您键入的字符会像其他任何字母(或数字或其他字符)一样被打印到控制台。
键盘将事件发送到计算机。一个事件说“扫描码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键?
这与“终端”(即终端仿真器应用程序)如何表示键无关。您将看到的是用于向上移动一行但转换为可打印形式的ANSI代码(ANSI转义序列)。
键盘硬件发送“扫描代码”,但是它们会被翻译并作为字符显示给命令行级应用程序。该键A变成一个字节:A
如果Shift键按下(或Shift键锁定),a
否则。
在符合ANSI的终端中,箭头键不会发送单个字符(ASCII字符集中没有用于箭头的代码),而是三个字符的“转义序列”:escape-[-A
。其他三个箭头键是escape-[-B, C, D
。
如果将相同的字符序列发送(回送)到旧的物理ANSI终端,则会使光标向上移动一行。许多程序,包括终端仿真器,都可以识别这些字符序列并执行适当的操作:终端仿真器将使光标向上移动(这是curses
库向四周移动光标的方式),但是bash
会拦截它并滚动历史记录。
为了避免在没有用光标在屏幕上移动的程序中将光标停在各处,您经常会在键盘输入中看到ESC显示为可打印序列^[
(因为转义对应于control-[
)。这实际上是由终端设备接口处理的;见stty(1)
。结果,向上箭头将显示为^[[A
。如果键入cat
,请按回车,然后按一些箭头键,您将在命令行中看到此内容。这也是您在控制台登录屏幕上看到的。
最后:Control,Alt和您提到的其他键不会映射到字符序列。它们会影响另一个按键发送的字符(如上面的a
/ A
示例),或者它们根本没有映射到文本。此类按键只能由侦听键盘事件的程序检测到。通过从标准输入读取(或将其写入文件)无法看到它们。
这种行为因外壳而异。大多数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
可以在其中清空)
login
,与无关bash
。
bash
并login
使用相同的库(readline)来编辑行。不同之处在于,login
它不会像将垂直箭头键一样解释为命令bash
。
^[
表示形式escape
,但是它们是不同的东西。Bash完全可以使用任何语法。实际上,当您编写时\[A
,bash输出三个字符:(^[
即转义)[
,,A
。
getty
或吞下login
,尽管我不确定为什么。有根据的猜测说,出于历史原因,内核专门解释了打印屏幕。但是,除修饰符外,我不确定100%可以使用。