规范输入与非规范输入终端的区别

55

我正在备考考试,对Unix(例如curses)中的规范输入/输出和非规范输入/输出工作方式感到困惑。我知道有一个缓冲区用于应用“行纪律”进行规范输入。这是否意味着非规范输入将绕过缓冲区,还是仅表示不会应用任何行纪律?这个过程在输入和输出操作中有何区别?

在我使用的演示规范输入的curses程序中,用户输入的内容会在键入一定数量的字符或经过一定的时间后自动输入。这些是否被视为“行纪律”,还是完全不同的东西?

1个回答

104
对于规范输入——想象一下shell;实际上,想象一下好老式的Bourne shell,因为Bash和相关程序具有命令行编辑。您输入一行输入;如果犯了错误,可以使用删除字符(默认是Backspace,通常是Delete)来删除前一个字符。如果完全搞砸了,可以使用"行终止符"(不完全标准化,通常是Control-X)取消整行。在某些系统中,使用Control-W进行单词删除。所有这些都是规范输入。整个行被收集并编辑,直到按下结束行字符——Return。然后,整行可以供等待程序使用。根据未完成的read()系统调用,整行将可用于读取(通过一个或多个read()调用)。
对于非规范输入——想象一下vivim或其他什么——您按下一个字符,它立即可供程序使用。您不必等到按下回车键。系统不会编辑字符;只要键入,它们就可以供程序使用。由程序适当地解释事情。现在,vim确实做了许多看起来有点像规范输入的事情。例如,退格键向后移动,并且在输入模式下删除了原来的内容。但那是因为vim选择使其行为如此。
Canonical和non-canonical输出并不是非常严重的事情。有一些细微的差别,涉及到是否在换行符前回车以及是否进行延迟(在电子设备上不必要;在输出设备可能是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编程书籍(至少是好的书籍)也会涵盖此内容。

2
那么对于非规范输入,输入缓冲区是否完全被绕过?此外,行纪律是在哪里发挥作用的? - titaniumdecoy
一个跟进的问题:假设我打开了两个vim终端(即两个正在监听按键的进程),并且一次只使用一个。为什么另一个vim终端会忽略我按下的键?Vim的实现是否包含某种“暂停”模式,其中除了一个终端外,所有终端都被暂停,而我正在键入的终端则被“恢复”? - mercury0114
@mercury0114 - 窗口系统处理“焦点”,确定在任何给定时间哪个(伪)终端接收按键。 - Jonathan Leffler

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接