SSH报错unknown terminal type怎么修复
SSH中的TERM名称若不在服务器terminfo数据库中,curses程序会报unknown terminal type并退出。将terminfo条目安装到主目录即可,无需root权限。
“unknown terminal type”的含义
通过 SSH 连接时,如果出现 unknown terminal type 错误,表示 TERM 中的名称在服务器上的 terminfo 数据库中没有匹配的条目。终端模拟器会在您的笔记本电脑上设置该名称。负责识别它的数据库位于远程计算机上。查找失败后,该服务器上的所有 curses 程序都会在绘制任何内容前退出,因为系统没有描述您的终端功能。
要保留终端模拟器的全部功能,只需执行一个命令:将您自己的 terminfo 条目编译到服务器上的 ~/.terminfo。ncurses 会在系统目录之前搜索您的主目录,因此无需 root 权限,也不会影响其他用户。
TERM 是名称,terminfo 是数据库
TERM 中只保存一个字符串,而该字符串只是一个键。terminfo 是一个经过编译的终端描述数据库,程序通过这个键查找正确的终端描述。描述中记录了终端支持的颜色数量、将光标移动到第 12 行第 40 列所需的字节、F5 键发送的字节,以及终端是否能够绘制带样式的下划线。ncurses 是 Linux 上几乎所有文本用户界面所依赖的库,它会在启动时读取该描述。没有它,top、less、nano 和 watch 等程序无法绘制任何屏幕。
查看您自己的条目:
echo "$TERM"
tput longname
infocmp -1 | head -20tput longname 输出 TERM 所指向条目的可读描述。对于 xterm-256color,它会输出:
xterm with 256 colorsinfocmp -1 反编译整个条目,并逐行输出每项功能。如果两个命令都能正常工作,说明这台机器上的数据库认识此终端。通过 SSH 连接后,远端也必须具备相同状态。
为什么只在 SSH 中出错
SSH 只发送名称,不发送其他内容。当客户端请求伪终端时,TERM 会随该请求发送。OpenSSH 手册明确说明:“只要请求伪终端,就始终会发送 TERM 环境变量,因为协议要求这样做。”因此,VPS 上的登录 shell 会获得 TERM=xterm-ghostty、xterm-kitty,或您的终端模拟器使用的其他名称。该名称对应的描述仍保存在您的笔记本电脑及其数据库中。在终端模拟器出现之前构建的服务器从未听说过这个名称。SSH 连接本身不会复制终端描述,这是有意设计的:协议传输的是名称,而不是终端能力信息。
使用一个肯定不存在的名称,在您自己的计算机上重现此故障:
TERM=xterm-nosuchthing tput colors
echo "$?"tput: unknown terminal "xterm-nosuchthing"退出状态为 3。ncurses 将其记录为未知终端类型或缺少数据库。每个 curses 程序都会执行相同的查找,因此同一个缺失名称会让不同程序显示不同消息,但根本原因相同。nano 会因无法在启动时加载描述而以 Error opening terminal: xterm-nosuchthing. 终止,这是 ncurses 的标准失败行为。vim 会打印 E558: Terminal entry not found in terminfo。less 会打印 WARNING: terminal is not fully functional。一个只能部分工作的分页器和一个拒绝启动的编辑器看起来像是无关的故障。它们实际缺少的是同一个文件。
ncurses 查找条目的位置
ncurses 按固定顺序查找,具体顺序记录在 terminfo(5) 中:
- 如果设置了
$TERMINFO,则只搜索该目录。 $HOME/.terminfo。$TERMINFO_DIRS中列出的所有目录。- 编译时内置的路径。在 Debian 和 Ubuntu 上,这些路径包括
/etc/terminfo、/lib/terminfo和/usr/share/terminfo。
在服务器上运行 infocmp -D,以输出该服务器自身 ncurses 构建所使用的目录列表,不要直接依赖上述路径。关键在第 2 步。系统会先搜索您的主目录,再搜索任何系统目录。因此,在 ~/.terminfo 下放置一个文件即可为您的账户修复查找问题,无需安装软件包,也无需 root 权限。
修复 1:使用服务器已知的 TERM
最快的临时解决方法是为某个连接指定其他终端:
TERM=xterm-256color ssh user@203.0.113.10在笔记本电脑的 ~/.ssh/config 中为该主机永久设置:
Host vps1
HostName 203.0.113.10
User deploy
SetEnv TERM=xterm-256color客户端需要使用 2018 年 8 月发布的 OpenSSH 7.8 或更高版本,SetEnv 才可用。TERM 是唯一不需要服务器许可的变量:手册说明,“与 SendEnv 类似,但 TERM 变量除外,服务器必须准备好接受该环境变量。”因此,即使连接到完全没有 AcceptEnv 行的加固版 sshd,也可以正常工作。
代价是:终端模拟器所描述的、超出纯 xterm-256color 的所有功能都会丢失。这包括通过 RGB 能力声明的 24 位颜色,以及通过 Smulx 实现的样式下划线。程序将无法再看到这些能力,因此会回退到 256 色和普通下划线。屏幕仍可正常使用,只是功能不如您选择的终端。
不要通过在服务器上的 .bashrc 中添加 export TERM=xterm-256color 来解决此问题。该文件会对每个连接执行,包括来自服务器已知终端的连接,因此会降低原本正常会话的功能。应将此覆盖设置保留在客户端,因为您知道客户端运行的是哪个终端模拟器。
修复方法 2:只需将 terminfo 条目发送到服务器一次
此方法可以保持终端模拟器不变。在本地反编译该条目,通过 SSH 传输,然后在远端重新编译:
infocmp -x | ssh user@203.0.113.10 -- tic -x -infocmp -x 会将当前 TERM 的条目输出为源文本,其中包括扩展功能(用户定义的功能)。tic -x 会在服务器上将该源文本重新编译为二进制描述。两端都需要使用 -x,否则 Smulx 等功能会在传输过程中丢失,最终部署的是功能降级的终端副本。
tic 可以写入系统目录时会写入该目录;如果用户没有写权限,则会回退到 $HOME/.terminfo。VPS 上的普通账户会使用主目录,这正是所需的行为。您也可以指定目标路径:
infocmp -x | ssh user@203.0.113.10 -- tic -x -o '~/.terminfo' /dev/stdin~/.terminfo 两侧的引号不是装饰。ssh 会将命令词连接为一个字符串,并将其交给远程 shell,因此未加引号的 ~ 会先由您的本地 shell 展开。这样发送到远程主机的会是字面量 /home/yourname/.terminfo,而该主机上的账户名称可能不同。tic 会因权限错误失败,或者将文件写入 ncurses 从不搜索的路径。为波浪号加引号,让远程 shell 负责展开它。
登录并检查:
ssh user@203.0.113.10
tput longname
ls -R ~/.terminfotput longname 输出您的终端描述,表示查找已成功;ls 显示已编译的文件位于以终端名称首字母命名的子目录下。然后运行 top,或者运行 watch -n1 uptime,它会通过同一库重绘屏幕,确认实际的 curses 程序可以正常绘制屏幕。
代价是:每台服务器需要执行一次,且该条目只存放在一台机器上的一个账户主目录中。重建 VPS 后,条目会丢失。将该命令加入您用于同时配置和管理多台服务器的工具中,这样新主机创建后就会自动带有已编译的条目。
修复 3:安装扩展 terminfo 数据库
如果您拥有 root 权限,并希望该名称对系统中的每个账户都能解析:
sudo apt update
sudo apt install ncurses-term
tput -T xterm-ghostty longnamencurses-term包含基础安装中未包含的终端描述。它会为 root 和其他所有用户修复该名称,而修复 2 无法做到这一点。
只有在您使用的终端条目存在于发行版打包的 ncurses 版本中时,它才有帮助,因此请先检查,不要直接假设。Ubuntu 24.04 提供 ncurses-bin 6.4+20240113-1ubuntu2.1(截至 August 2026)。Ghostty 的条目是在上游 ncurses 6.5-20241228 中添加的,版本更新,因此在 Ubuntu 24.04 上,apt install ncurses-term 无论运行多少次都无法生成 xterm-ghostty 条目。tput -T <name> longname用于检查:条目存在时,它会打印描述;条目不存在时,unknown terminal会以退出状态 3 结束。
如果不想安装整个软件包,而只想在系统范围内安装单个条目,请以 root 身份复制源文件并进行编译:
infocmp -x | ssh user@203.0.113.10 -- 'cat > /tmp/term.src'
ssh -t user@203.0.113.10 -- sudo tic -x -o /usr/share/terminfo /tmp/term.src第二条命令中的 -t会分配一个伪终端,因此 sudo可以提示输入密码。没有它,sudo可能会以 sudo: no tty present and no askpass program specified退出。
让终端仿真器执行传输
一些终端仿真器提供了可自动执行修复 2 的辅助功能。kitty 提供了一个 ssh kitten:kitten ssh myserver 会连接远程主机,并自动将 kitty 的 terminfo 复制到远程主机。其文档还给出了手动形式 infocmp -a xterm-kitty | ssh myserver tic -x -o \~/.terminfo /dev/stdin,其中的波浪号已按上述原因进行转义。Ghostty 记录了 infocmp -x xterm-ghostty | ssh YOUR-SERVER -- tic -x -,并提供 shell 集成(ssh-env 和 ssh-terminfo)以及 +ssh 操作,可自动完成这两项修复。
这些辅助功能执行的命令与您刚才手动执行的命令相同。了解手动形式仍然很重要,因为当连接是在其他位置发起时,例如跳板主机上或脚本中,辅助功能无法执行。
错误再次出现时
在 sudo -i 下。 以 root 身份启动的登录 shell 设置了 HOME=/root,而 sudo 保留了您的 TERM。ncurses 现在会搜索 /root/.terminfo,但其中没有您的条目,因此只有 root 会再次失败。使用 sudo -i env 确认,并读取 HOME 和 TERM 行。将该条目安装到系统目录,或将副本放入 /root/.terminfo。
在 tmux 或 screen 内。 它们会为其中运行的程序设置自己的 TERM,通常是 screen-256color 或 tmux-256color。较旧的服务器认识 screen-256color,但可能不认识 tmux-256color,因此外部 shell 工作正常,而会话内的所有程序都失败。原因相同,只是名称不同。在服务器上运行 tput -T tmux-256color longname,查看它具有这两个名称中的哪一个。一个 基于 tmux 构建的终端工作台 会掩盖这个问题,直到您在尚未修复的主机上连接会话。
在新服务器上。 ~/.terminfo 按账户和机器分别保存,因此重建后的 VPS 又会从空配置开始。
屏幕显示正常,但按键异常。 如果显示正常,但 Home、End 或功能键会插入多余字符,说明解析出的名称对应了一个与您的终端不匹配的条目。按键序列与绘制能力来自同一个 terminfo 条目,因此近似条目只能提供近似的按键行为。这通常是修复方法 1 在按键序列不同于 xterm 的模拟器上的结果。修复方法 2 才是正确做法,因为只有您所用模拟器的实际条目包含正确的按键序列。
FAQ
为什么通过 SSH 只能看到“未知终端类型”?
因为必须保存终端条目的数据库位于服务器上。终端模拟器会将自身描述安装在运行它的计算机上,因此本地程序无需你进行任何操作即可找到该描述。SSH 只发送 TERM 的值,因为该协议会在伪终端请求中携带这个名称。远程 ncurses 在远程数据库中查找该名称,但找不到,因此 initscr 失败,程序随即停止。
不使用服务器上的 root,可以解决这个问题吗?
可以。ncurses 会先搜索 $HOME/.terminfo,然后才搜索系统目录,因此只要在该目录中放置条目即可供你的账户使用。每台服务器运行一次 infocmp -x | ssh user@host -- tic -x -。无法写入系统路径时,tic 会将条目写入你的主目录;对于非特权账户,这是通常情况。登录后运行 tput longname,确认现在可以解析该条目。
为主机设置 TERM=xterm-256color 会失去什么功能?
终端模拟器所描述的、超出 xterm-256color 条目的所有功能,例如通过 RGB 提供的 24 位颜色,以及通过 Smulx 提供的带样式下划线。程序无法看到这些功能,因此会使用最接近的回退设置。功能键序列也可能与实际终端不同。应在客户端的 ~/.ssh/config 中设置该选项,而不是写入服务器上的 .bashrc;后者会降低原本已正常工作的终端会话的功能。
为什么 sudo -i 后错误会再次出现?
sudo -i 会使用 HOME=/root 以 root 身份启动登录 shell,同时保留你的 TERM 值。此时 ncurses 会搜索 /root/.terminfo,而不是你的主目录,因此找不到条目,root 看到的仍是相同错误,而你的账户已经不再出现该错误。运行 sudo -i env,检查 HOME 和 TERM 行。使用 sudo tic -x -o /usr/share/terminfo 将条目编译到系统目录,或将其复制到 /root/.terminfo。
apt install ncurses-term 总能解决这个问题吗?
不能。它只会添加发行版打包的 ncurses 版本中已有的条目。Ubuntu 24.04 发布时使用 ncurses 6.4(截至 2026 年 8 月为 ncurses-bin 6.4+20240113-1ubuntu2.1),而 Ghostty 的条目是在 ncurses 6.5-20241228 上游版本中添加的,因此该软件包不可能包含该条目。依赖软件包前,先使用 tput -T <name> longname 检查;如果检查结果仍为未知终端,请自行安装该条目。