非常有趣的问题,即使它有点开放式。
正如@tripleee 所述,ncurses 是交互式 CLI 应用程序的基础库。
一点历史...
终端 == "打印机" ...
要了解 POSIX “终端”,您必须考虑它们的历史……更具体地说,您需要考虑在 70 年代您将键盘+打印机连接到串行电缆上的“终端”意味着什么.在您键入时,字节流会流向大型机,主机会将它们回显到打印机,从而导致打印机在您键入命令时回显该命令。然后,通常在按 ENTER 后,大型机会关闭并做一些工作,然后将输出发送回以进行打印。因为它基本上是一个美化的点阵打印机,所以我们在这里只讨论附加。没有“画屏”之类的花哨的东西。
试试这个:
echo -e "Hi there\rBye"
你会看到它打印出“Bye there”。 "\r" 是没有换行的回车。 carriage 是在旧的点阵打印机中来回移动并实际进行打印的打印机部件。因此,如果您将回车返回到页面的左侧并且无法前进纸张(即“换行”),那么您将开始打印当前的文本行。 “终端” == “打印机”。
显示器和软件终端...仍然面向行
所以稍微向前一点,一种称为“显示器”的革命性技术出现了,您可以在其中拥有可以重写的虚拟化终端显示器。因此,像所有优秀的技术一样,我们通过添加越来越多的特殊转义码进行渐进式创新。例如,查看ANSI color codes。如果您在无法识别这些转义码的终端上,您会在这些未解释代码的输出中看到一堆乱码:
"methodName": ESC[32m"newInstance"ESC[39m,
"fileName": ESC[32m"NativeConstructorAccessorImpl.java"ESC[39m,
"className": ESC[32m"sun.reflect.NativeConstructorAccessorImpl"ESC[39m,
"nativeMethod": ESC[33mfalseESC[39m,
当您的终端看到 '\033' (ESC)、'['、...、'm' 时,它会将其解释为更改颜色的命令。试试这个:
echo -e "\033[32mgreen\033[39m"
无论如何,这就是 Unix 终端系统的历史/遗产,后来被 Linux 和 BSD(例如,macs)继承,并半标准化为POSIX。查看termio.h,它定义了与终端交互的内核接口。几乎可以肯定,Linux/BSD 有许多更高级的功能,这些功能并未完全标准化为 POSIX。在谈论“标准”的同时,还有一堆事实上的终端设备协议标准,比如古老的VT100。像 SSH 或 PuTTY 这样的软件“终端模拟器”知道如何说 VT100,而且通常还会说一堆更高级的方言。
将鞋钉“交互”到“面向线路”的界面...
所以……交互式……这并不适合行式打印机的世界观。它在上面分层。输入很容易;而不是自动回显每个键入的击键并等待 ENTER(ala "readline"),我们让程序在击键来自 TTY 时消耗它们。输出更复杂。尽管基本抽象是输出的流,但如果有足够的转义码,您可以通过定位"caret" 并在旧文本之上写入新文本来重新绘制屏幕(就像我的 "\r “ 例子)。自己实现这些都不是一件有趣的事,尤其是当您想支持具有不同转义码的多个环境时。 .... 因此,ncurses 是其中最著名的库之一。要了解高效将动态屏幕渲染到面向行的 TTY 中的时髦魔法,请查看“A Hacker's Guide to NCURSES”中的Output and Screen Updating。