故事的开端是这样的,emacs下面大家知道search的快捷键是Ctrl-S,在终端下使用也很正常。但有时候会一不小心在非emacs下按到这个键(比如…vim? XDDD)。

接着发生的事情就好像自己学了那么多年vim还是发现自己一无所知那样的无奈——终端锁住了,按什么都没反应…

偶尔一次从某同事那里得知这是一个终端的功能,需要按Ctrl-Q解除,立即尝试,有效。这样一来虽然解除了「vim还不至于有这样的坑」的疑问,但又冒出来一个问题,这个快捷键到底是做什么的…?

Google老师博大精深,某找到一篇有关这个疑问的问答,呃,虽然不是stackoverflow,不过还是一家的stackexchange啦XDD

有两个回答比较有内容,一则讲了个有关这个问题来龙去脉的故事,一则讲了如何关闭这个功能的办法。先说后面一则吧XDD

如何解除Ctrl-S锁定的终端

短回答: Ctrl-Q

长回答: 如果想要关闭该功能,可以使用stty -ixon,相对地,打开即stty ixon。如果想让任何按键都能再启动,使用stty ixany

有关stty的选项,可以man stty。对于这两项的说明为:

[-]ixon
       enable XON/XOFF flow control

开启XON/XOFF的流控制

* [-]ixany
       let any character restart output, not only start character

允许(输入)任何字符来重新开始输出,不仅限于开始字符

此功能和shell以及终端程序(比如模拟器)都没有关系,只和操作系统的终端驱动有关。

比较有趣的是,关闭XON/XOFF后,emacs mode的bash下Ctrl-S的功能就和Ctrl-R一样,只是顺序相反,和emacs的search一样啦XDD)

Ctrl-S锁定终端是用来做什么的?

这段某就直接拿翻译来解释吧XDDD

Ctrl-Q确实是正确解答,不过我还是来讲点故事补充一下空白的知识部分吧。

早在黑暗时期,终端还是通过长长的电线或者电话线及Modem连接到远程设备(其实还是个终端设备,不过使用电传机打字总比敲电报机的信号要来的容易多了)的大型装置。当初Unix正处于开发中时,ASCII码已经建立的非常完善(虽然竞争地位IBM的EBCDIC码也不容小觑)。

最早的终端,只要字符的接收速度没有超过打印头打印的速度,对于接受到的没一个字符都保留一份记录。不过随着基于CRT的终端设备出现,有个问题随着显现出来,CRT上只能显示25行内容,所以大家都认为25行80个字符的内存容量足以显示这些内容,甚至没人认为超过这个范围、滚动到屏幕外的字符不再需要更多的内存。

所以就需要定一个规矩来让发送操作根据信号来满足阅读的人的阅读速度。

7位的ASCII码里有33个码用来作控制字符(0到31以及127)。其中一些的目的非常完善,比如NUL(纸带控制符的空白开头符号),DEL(用来标记错误的内容,打7个孔),BEL(叮!),CRLFTAB。另外有4个被明确地定义为控制终端本身(DC1DC4,也即 Ctrl+Q、Ctrl+R,Ctrl+S和Ctrl+T)。

我猜想取名的是某种助记符,“S”是“Stop”,而“Q”是“Continue”,这还算不赖;把DC3分配为「请停止发送」,而DC1是“好吧,现在继续发”。

当Unix走出Bell实验室,面向全世界时,这套规则已经建立完善。

同时这套规则也叫做“流控制软实现”,在串行设备中极其常见。由于它在通信频道里阻止了这几个字符用于其他任何用途,Stop信号必须在处理其后任何字符前优先处理来避免发送给接收端过多的字符内容,所以此功能很难正确实现。 (译者注:某猜想这里因为输入和终端接受数据用的是同一条通信频道。)

在实际中,应用更广泛的做法是在串行数据流所在的数据带(band)外使用额外的信号。直接在支持额外信号线的有线连接上,有硬件的握手过程,这样可以将这些字符内容移作它用。

当然,如今的终端窗口不再使用物理串行接口,带滚动条,也不再需要使用软件实现的握手过程,不过当初的规定一直保留下来。

我还记得RMS在第一版emacs实现里想把增量搜索功能映射到Ctrl+S时的抱怨,他当时依赖7位软件实现的流控制地用户们表现地十分无情。

文中提到的纸带(paper tape)如果不明白可以看这里的维基百科条目DEL为什么是打7个孔呢?以前的数据存储没有可擦除的介质,机器是识别纸带上的孔,所以使用DEL删除(原文使用了“cross out”字眼,还记得打字机时代回退回去,用“x”键来“叉”掉错误的内容吗?XDDDD),某估计是机器用来识别错误内容的吧,条目里没提到具体的型号。

从故事里某感受到以前计算机设备的古老和有趣XDDD 现在我们的真终端(tty)其实和以前的串行设备终端比起来已经强大多了XDDD

此外还有提及多次,也是在那个年代左右,诞生了screen这样的救星程序来减少各种烦恼。(当然啦,前后故事也应该有上个几年的啦XDDD)

__END__