对于规范输入——想想 shell;实际上,想想老式的 Bourne shell,因为 Bash 和亲戚都有命令行编辑。你输入一行输入;如果输入有误,则使用擦除字符(默认为 Backspace,通常;有时是 Delete)来擦除前一个字符。如果完全搞砸了,可以用line kill 字符取消整行(不完全标准化,经常是Control-X)。在某些系统上,您可以使用 Control-W 来擦除单词。所有这些都是规范输入。整行被收集和编辑,直到行尾字符 - Return - 被按下。因此,整条线路可供等待程序使用。根据未完成的read() 系统调用,整行都可以读取(通过一次或多次调用read())。
对于非规范输入——想想vi 或vim 或其他任何东西——你按下一个字符,它就会立即可供程序使用。直到您返回时,您才会被阻止。系统不对字符进行编辑;它们在输入后立即可供程序使用。由程序来适当地解释事物。现在,vim 确实做了一些看起来有点像规范输入的事情。例如,退格键向后移动,在输入模式下会擦除那里的内容。但那是因为vim 选择让它表现得像那样。
规范和非规范输出是一个不那么严肃的事情。有一些点点滴滴的差异,例如是否在换行之前回显回车,以及是否进行延迟(对于电子设备来说不是必需的;在输出设备可能是 110- 的日子里很重要波特电传)。它还可以处理诸如处理不区分大小写的输出设备之类的事情——又是电传打字机。小写字母以大写字母输出,大写字母以反斜杠和大写字母输出。
过去,如果您在登录提示符中输入所有大写字母,那么登录程序将自动转换为所有大写字母输出的模式,每个实际大写字母前都有一个反斜杠。我怀疑这不再在电子终端上完成。
TitaniumDecoy 在评论中问道:
那么对于非规范输入,输入缓冲区是否被完全绕过?另外,线路学科从何而来?
对于非规范输入,仍然使用输入缓冲区;如果没有带有read() 调用的程序等待来自终端的输入,则字符将保存在输入缓冲区中。不会发生输入缓冲区的任何编辑。
行规则类似于输入编辑所做的一组操作。因此,行规则的一个方面是擦除字符在规范输入模式中擦除先前的字符。如果您设置了icase(输入大小写映射),则除非前面有反斜杠,否则大写字符将映射为小写;我相信那是一个线路学科,或者是线路学科的一个方面。
我忘了提到EOF处理(Control-D)是在规范模式下处理的;它实际上意味着'使read() 可以使用累积的输入';如果没有累积输入(如果您在行首键入 Control-D),则 read() 将返回零字节,然后程序将其解释为 EOF。当然,之后你可以愉快地在键盘上输入更多字符,忽略 EOF(或以非规范模式运行)的程序会很开心。
当然,在规范模式下,在键盘上键入的字符通常会回显到屏幕上;您可以控制是否发生回显。然而,这与规范输入有些相切;即使关闭回声,也可以进行正常编辑。
同样,中断和退出信号是规范模式处理的产物。诸如 Control-Z 之类的作业控制信号也是如此,用于暂停当前进程并返回到 shell。同样,流控制(Control-S,Control-Q 停止和开始输出)由规范模式提供。
Rochkind 的Advanced Unix Programming, 2nd Edn 的第 4 章涵盖了终端 I/O 并提供了大部分此类信息 - 以及更多信息。其他 UNIX 编程书籍(至少是好的书籍)也将涵盖它。