规范与非规范终端输入

Posted

技术标签:

【中文标题】规范与非规范终端输入【英文标题】:Canonical vs. non-canonical terminal input 【发布时间】:2010-09-26 09:05:52 【问题描述】:

我正在准备考试,我对 Unix 中规范与非规范输入/输出的工作方式感到困惑(例如,curses)。我知道有一个缓冲区适用于规范输入的“线路规则”。这是否意味着非规范输入绕过了缓冲区,还是仅仅意味着没有应用任何线路规则?这个过程对于输入和输出操作有何不同?

在我使用过的用于演示规范输入的 curses 程序中,用户输入的输入是在输入一定数量的字符或经过一定时间后自动输入的。这些东西中的任何一个都被认为是“线学科”还是完全是其他东西?

【问题讨论】:

【参考方案1】:

对于规范输入——想想 shell;实际上,想想老式的 Bourne shell,因为 Bash 和亲戚都有命令行编辑。你输入一行输入;如果输入有误,则使用擦除字符(默认为 Backspace,通常;有时是 Delete)来擦除前一个字符。如果完全搞砸了,可以用line kill 字符取消整行(不完全标准化,经常是Control-X)。在某些系统上,您可以使用 Control-W 来擦除单词。所有这些都是规范输入。整行被收集和编辑,直到行尾字符 - Return - 被按下。因此,整条线路可供等待程序使用。根据未完成的read() 系统调用,整行都可以读取(通过一次或多次调用read())。

对于非规范输入——想想vivim 或其他任何东西——你按下一个字符,它就会立即可供程序使用。直到您返回时,您才会被阻止。系统不对字符进行编辑;它们在输入后立即可供程序使用。由程序来适当地解释事物。现在,vim 确实做了一些看起来有点像规范输入的事情。例如,退格键向后移动,在输入模式下会擦除那里的内容。但那是因为vim 选择让它表现得像那样。

规范和非规范输出是一个不那么严肃的事情。有一些点点滴滴的差异,例如是否在换行之前回显回车,以及是否进行延迟(对于电子设备来说不是必需的;在输出设备可能是 110- 的日子里很重要波特电传)。它还可以处理诸如处理不区分大小写的输出设备之类的事情——又是电传打字机。小写字母以大写字母输出,大写字母以反斜杠和大写字母输出。

过去,如果您在登录提示符中输入所有大写字母,那么登录程序将自动转换为所有大写字母输出的模式,每个实际大写字母前都有一个反斜杠。我怀疑这不再在电子终端上完成。


TitaniumDecoy 在评论中问道:

那么对于非规范输入,输入缓冲区是否被完全绕过?另外,线路学科从何而来?

对于非规范输入,仍然使用输入缓冲区;如果没有带有read() 调用的程序等待来自终端的输入,则字符将保存在输入缓冲区中。不会发生输入缓冲区的任何编辑。

行规则类似于输入编辑所做的一组操作。因此,行规则的一个方面是擦除字符在规范输入模式中擦除先前的字符。如果您设置了icase(输入大小写映射),则除非前面有反斜杠,否则大写字符将映射为小写;我相信那是一个线路学科,或者是线路学科的一个方面。


我忘了提到EOF处理(Control-D)是在规范模式下处理的;它实际上意味着'使read() 可以使用累积的输入';如果没有累积输入(如果您在行首键入 Control-D),则 read() 将返回零字节,然后程序将其解释为 EOF。当然,之后你可以愉快地在键盘上输入更多字符,忽略 EOF(或以非规范模式运行)的程序会很开心。

当然,在规范模式下,在键盘上键入的字符通常会回显到屏幕上;您可以控制是否发生回显。然而,这与规范输入有些相切;即使关闭回声,也可以进行正常编辑。

同样,中断和退出信号是规范模式处理的产物。诸如 Control-Z 之类的作业控制信号也是如此,用于暂停当前进程并返回到 shell。同样,流控制(Control-SControl-Q 停止和开始输出)由规范模式提供。

Rochkind 的Advanced Unix Programming, 2nd Edn 的第 4 章涵盖了终端 I/O 并提供了大部分此类信息 - 以及更多信息。其他 UNIX 编程书籍(至少是好的书籍)也将涵盖它。

【讨论】:

那么对于非规范输入,是否完全绕过了输入缓冲区?另外,线学科从何而来? 一个后续问题:假设我打开了两个 vim 终端(即两个正在运行的进程监听击键)并且当时正在使用一个。为什么其他 vim 终端忽略我按下的键? vim 的实现是否包含某种“暂停”模式,其中除了一个终端之外的所有终端都暂停,而我正在输入的终端是“恢复”? @mercury0114 — 窗口系统处理“焦点”,确定在任何给定时间哪个(伪)终端接收击键。

以上是关于规范与非规范终端输入的主要内容,如果未能解决你的问题,请参考以下文章

终端错误中的 SQL:不匹配的输入 ')' 期望(在原始类型规范中靠近 'VARCHAR'

代码的规范终端响应式布局

终端模式

终端模式

如何使用可可豆荚在终端中安装 Firebase 身份验证?

网络安全与规范管理解决方案