Terminfo(以前称为 Termcap)是一个终端能力及其它信息的数据库。对于几乎每种终端型号,它都告诉应用程序该终端能够做什么。它说明了要发送到终端的转义序列(或控制字符),以便执行诸如将光标移动到新位置、擦除屏幕的一部分、滚动屏幕、更改模式、更改外观(颜色、亮度、闪烁、下划线、反色视频等)之类的操作。大约在 1980 年之后,许多终端支持超过一百种不同的命令(其中一些命令带有数字参数)。
terminfo 向应用程序提供信息的一种方式是通过程序员可以放入 C 程序中的 “ncurses” 函数。例如,如果程序想要将光标移动到第 3 行,第 6 列,它只需调用:move(3,6)。move() 函数(ncurses 的一部分)知道如何为您的终端执行此操作(它已读取 terminfo)。因此,它会向终端发送适当的转义序列,以便为特定终端进行此特定移动。有些程序直接从 terminfo 文件获取信息,而无需使用 ncurses。因此,不需要 ncurses 的 Linux 软件包可能仍然需要适用于您的终端的 terminfo 文件。
terminfo 的缩写通常比 termcap 的缩写更长,因此更容易猜测它们的含义。terminfo 的手册页更加详细(并且包含旧的 termcap 缩写)。此外,termcap 条目有大小限制,而 terminfo 没有。因此,除非您已经致力于使用 termcap,否则建议您使用 terminfo。
terminfo 数据库是编译过的,因此具有源文件部分和编译文件部分。旧的 termcap 数据库只有源文件部分,但是此源文件可以通过单个命令转换为 terminfo 源文件,然后进行编译。因此,您可以在没有任何 terminfo 源文件的情况下使用,因为 termcap 源文件可以创建编译后的 terminfo 数据库。要查看您当前使用的终端(包括 PC 监视器)的数据库显示,请键入 “infocmp”,您应该看到它的源 terminfo “文件”。
要查看您的终端(例如 vt100)是否在 terminfo 数据库中,请键入 “locate vt100”。如果您需要查找终端的 terminfo 名称,请浏览编译数据库中的文件列表,或参阅 我的终端的 terminfo 名称是什么?
键入 “locate vt100” 可能会显示 /usr/lib/terminfo/v/vt100、/usr/share/terminfo/v/vt100、/home/.../.terminfo/v/vt100 和/或 /etc/terminfo/v/vt100。所有这些都是编译后的 terminfo 文件的可能位置。虽然 /etc/terminfo 目录不是它的标准位置,但在 /usr 目录不可访问的情况下,在那里放置一些终端类型可能很有用。例如,/usr 可能位于未成功挂载的单独磁盘或分区上。通常,使用您的主 terminfo 数据库的程序如果它位于上述至少一个位置,则能够找到它。否则,可以将环境变量 TERMINFO 设置为指向此数据库的路径。示例:TERMINFO=/usr/share/terminfo
对于 Debian Linux 发行版,几个常用的终端(包括监视器控制台)位于 ncurses-term 软件包中。这些都放在 /etc/terminfo/ 中。数据库中的所有终端都位于 ncurses-bin 软件包中,并放在 /usr/share/terminfo/ 中。
如果编译后的 terminfo 位于多个位置,通常一切正常,直到有人安装新的 terminfo 文件(来自较新的发行版、来自网络、通过编辑旧文件等)。每个新的 terminfo 文件都应替换该文件的所有现有旧副本(在不同位置),除非您废除冗余位置。如果您不确保完成此操作,那么某些应用程序可能会最终仍然找到并使用仍然存在于 “可能” 位置的旧(且可能存在错误)的 terminfo 数据。将环境变量 TERMINFO 设置为最新的位置(如上所述)将有助于避免此问题。
虽然源代码文件可能未安装在您的计算机上,但如果您有编译后的代码,还有另一种获取源代码的方法。只需使用 “infocmp
” 命令。
源代码文件(对于所有终端)可能是 /etc/termcap 和/或 terminfo.src(或其他名称)。有关创建(或修改)这些源文件所需的格式,请参阅手册页:terminfo(5) 或 termcap(5)。文件 terminfo.src 可能位于您计算机上的各个位置,或者它可能未包含在您的 Linux 发行版中。使用 locate
命令尝试查找它。它在网上可用,网址为 http://catb.org/terminfo/。
源文件中的数据使用 “tic” 程序进行编译,该程序能够termcap 格式和 terminfo 格式之间进行转换。因此,您可以从 termcap 源文件创建编译后的 terminfo 数据库。用于安装 Linux 的安装程序可能已将编译后的文件安装在您的硬盘上,因此您无需编译任何内容,除非您修改 /etc/termcap(或 terminfo.src)。“tic” 会自动将生成的编译文件安装到 terminfo 目录中,以供应用程序使用。它安装在哪个位置取决于 ... 请参阅 “man tic” 以获取说明。
最好查看一下您正在使用的终端的 terminfo 条目(当然是源代码),并阅读注释。快速检查它而无需注释的方法是只需键入 “infocmp”。但是注释可能会告诉您有关终端的一些特殊信息,例如您需要如何设置它,以便它可以与 terminfo 数据库正确配合使用。
为了节省磁盘空间,可以删除除您拥有(或将来可能需要)的终端类型之外的所有 terminfo 数据库。不要删除任何 “Linux 终端”(控制台)的 termcap 或用于 x 终端模拟(例如 xterm)的 termcap。“dumb” 终端类型在应用程序无法确定您正在使用的终端类型时可能需要。如果安装程序仅安装您拥有的终端的 terminfo,并且您可以在几秒钟内在 Internet 上获取新安装的终端的 termcap,则可以节省磁盘空间。
不幸的是,terminfo 和 termcap 文件中存在许多错误(bug)。此外,许多 terminfo 文件不完整,并且未定义终端上可用的某些功能。有时您可以不用修改 terminfo 就可以解决问题,但在其他情况下,您需要修改它,或者可能使用另一个具有良好 terminfo 的模拟。
提供的 terminfo 文件的糟糕状态是由于多种原因造成的。其中一个原因是,在 1980 年代,当其中许多文件被编写时(通常以 termcap 格式),应用程序没有利用更高级的终端功能。因此,如果 termcap(或 terminfo)文件中没有此类功能,则没有人抱怨。此外,编写 termcap 通常由短缺的志愿者完成。如今,诸如 vim 之类的程序使用 “上下文突出显示”,而 minicom 使用终端的图形字符集。这些通常需要向旧的 termcap 添加更多定义。这可能(或可能没有)已经完成。
大多数终端都有硬件错误(在其固件中),有时通过修改 termcap 来 “修复” 这些错误。然后,制造商可能会发出更换芯片,这将修复该错误。并非所有所有者都会费心去获取更换芯片。因此,您的终端可能存在 2 个或更多 terminfo,具体取决于它所具有的固件芯片。这种情况通常未在 termcap 中注明,并且 Linux 可能仅提供其中一个 termcap。过去几乎从未使用过的功能的某些硬件错误可能从未得到修复。此外,一些报告的硬件错误可能从未得到修复,因为它们在当时并不重要,或者因为终端制造公司倒闭了等等。
要做到这一点,您需要一份终端手册,其中显示了它使用的转义序列。来自 1990 年代的新手册通常不显示这一点。您还需要 terminfo 手册(手册页 “terminfo” 就是其中之一)。编辑 terminfo 源文件后,使用 “tic” 编译它。“tic” 应该自动将编译后的 terminfo 文件放入为其保留的正确目录中。
如果您想为某个终端找到比提供的更好的 terminfo 条目,您可以尝试在 Internet 上搜索(但您找到的可能更糟)。如果您的新 terminfo 条目比旧的更好,并且看起来稳定(您已经使用了一段时间,没有问题),那么您应该将副本发送给 terminfo 的维护者,如 terminfo(或 termcap)的源文件开头所述。
terminfo 中通常包含几个初始化字符串,这些字符串可以发送到终端以初始化它。这可能会更改屏幕的外观、更改终端所处的模式,和/或使终端模拟另一个终端。不会自动将初始化字符串发送到终端以初始化它。人们可能期望 getty 程序应该这样做。如果它这样做,人们可以更改存储在终端内部的设置,但是这种更改不会发生,因为初始化字符串会覆盖它。应用程序似乎也不会初始化(每个 terminfo 发送一个初始化字符串)。
要实际发送初始化字符串,您必须使用在命令行(或 shell 脚本(如 /etc/profile)中给出的命令。此类命令包括:“reset”、“tset”、“tput init” 或 “setterm -initialize”。有时无需发送初始化字符串,因为终端在开机时可能会正确设置自身(使用已设置并保存在终端非易失性存储器中的选项/首选项)。
环境变量 TERM 应该设置为您正在使用的终端的名称。如果尚未设置 TERM 并且您不知道终端的名称,请参阅 我的终端的 terminfo 名称是什么?。它通常由传递给 getty 程序的 terminal_type 参数设置(在 /etc/inittab 文件中查看它)。此名称必须在 Terminfo 数据库中。只需在命令行键入 “set” 即可查看 TERM 设置为什么(或键入:tset -q)。在控制台(监视器)上,TERM 设置为 “linux”,它是模拟名为 “linux” 的虚构终端模型的 PC 监视器。由于 “linux” 接近 vt100 终端,并且许多文本终端也是如此,“linux” 名称有时可以用作文本终端的临时权宜之计。
如果可以将多种类型的终端连接到同一端口 (/dev/ttyS...)(例如,如果有交换机允许不同类型的终端使用同一串行端口,或者如果端口连接到调制解调器,人们可以从不同类型的终端呼叫),则每次有人连接到串行端口时都需要设置 TERM。通常有一个查询转义序列,以便计算机可以询问终端的类型。另一种方法是要求用户键入(或选择)她/他正在使用的终端类型。您可能需要为此使用 tset 或编写一个简短的 shell 脚本来处理此问题。
一种方法是使用 “reset”(与 “tset” 相同;请参阅手册页)。reset 尝试确定您正在使用的终端的终端名称。然后,它在 terminfo 中查找数据并向您的终端发送初始化字符串。它还可以设置 TERM 的值。例如,用户拨入并登录。.profile 登录脚本被执行,其中包含以下语句:eval `tset -s ?vt100`。这导致:询问用户她/他是否正在使用 vt100。用户要么回答是,要么键入她/他正在使用的实际终端类型。然后 “reset” 发送初始化字符串并将 TERM 设置为此终端名称(类型)。