了解 Return、Enter 和 stty icrlf

Mat*_*t R 6 terminal stty

在 Ubuntu/gnome-terminal 中,如果我运行:

$ stty -icrnl
Run Code Online (Sandbox Code Playgroud)

然后启动 GHC 交互环境(一个 Haskell 控制台):

$ ghci
Run Code Online (Sandbox Code Playgroud)

然后按Return不提交行;然而,Enter确实如此。

但是,与:

$ stty icrnl
Run Code Online (Sandbox Code Playgroud)

双方ReturnEnter提交该行。

我不太理解这种行为;Return在这两种情况下肯定会提交换行符吗?

Gil*_*il' 11

理解发生了什么的第一步是意识到实际上有两个“换行”字符。有回车(CR,Ctrl+ M)和换行(LF,Ctrl+ J)。在电传打字机上,CR 将打印头移动到行首,而 LF 将纸张向下移动一行。对于用户输入,只有一个相关的概念,即“用户已经输入完一行”,但不幸的是出现了一些分歧:Unix系统,以及非常流行的C语言,使用换行来表示换行;但是当用户按下ReturnEnter键时,终端会发送回车。

icrnl设置告诉内核中的终端驱动程序在输入时将 CR 字符转换为 LF。这样,应用程序只需要关心一个换行符;在文件中结束行的同一个换行符也会结束终端上用户输入的行,因此应用程序不需要为此设置特殊情况。

默认情况下,ghci,或者更确切地说它使用的haskeline库,有一个键绑定Ctrl+ J,即 LF,以停止累积输入并开始处理它。它对Ctrl+M即 CR没有约束力。因此,如果终端未将 CR 转换为 LF,则 ghci 不知道如何处理该字符。

Haskeline 指示终端报告带有转义序列的键盘键。它查询终端的terminfo 设置以了解这些转义序列是什么(kentterminfo 数据库中的条目)。(terminfo 数据库也知道如何启用键盘转义:它发送smkx转义序列,并rmkx在退出时发送以恢复默认的键盘字符模式。)当您Enter在 ghci 中按下键盘上的键时,会发送转义sequence \eOM,haskeline 将其识别为停止累积输入并开始处理它的绑定。


Tho*_*key 6

提到ReturnEnter听起来好像你分别描述了键盘主要部分和数字小键盘上的键,通常位于主要部分的右侧:

在此处输入图片说明

但是,只有第一个对应于(未修改的)发送的密钥controlM。数字小键盘上的键可能会发送回车或其他任何内容,但实际上可能会发送转义序列,例如escapeOM,对于类似 VT100 的终端。

您可以通过回显它们来查看不同的键值,例如,使用cat -v.