SSD Nodes Learn Hosting plans →
指南 Matt Connor作者: Matt Connor

如何修正 SSH 的 unknown terminal type 錯誤

SSH 傳送的 TERM 名稱若不在伺服器 terminfo 資料庫中,curses 程式就會失敗。將 terminfo 編譯到家目錄即可修正,無需 root 權限。

Verified Every command ran end-to-end on a fresh Ubuntu 24.04 server, August 13, 2026.

What 「unknown terminal type」 means

透過 SSH 出現 unknown terminal type 錯誤,表示 TERM 中的名稱在伺服器上的 terminfo 資料庫中找不到相符的項目。終端機模擬器會在您的筆電上設定這個名稱,但必須由遠端機器上的資料庫辨識它。查詢失敗時,該伺服器上的所有 curses 程式都會在繪製任何內容前停止,因為系統沒有描述您終端機功能的資料。

若要保留終端機模擬器的所有功能,只需執行一個指令:將自訂的 terminfo 項目編譯到伺服器上的 ~/.terminfo。ncurses 會先搜尋您的家目錄,再搜尋任何系統目錄,因此不需要 root 權限,也不會變更其他使用者的設定。

TERM 是名稱,terminfo 是資料庫

TERM 儲存一個字串,而該字串只有一個索引鍵。terminfo 是編譯後的終端機描述資料庫,程式會使用這個索引鍵尋找正確的描述。描述會記錄終端機支援的色彩數量、將游標移至第 12 列第 40 欄所需的位元組、F5 按鍵送出的位元組,以及是否能繪製帶樣式的底線。Linux 上幾乎所有文字使用者介面都建置於其上的 ncurses,會在啟動時讀取這項描述。像 top、less、nano 和 watch 這類程式,若沒有這項描述,就無法繪製任何畫面。

查看自己的項目:

echo "$TERM"
tput longname
infocmp -1 | head -20

tput longname 會列印 TERM 所指定項目的可讀描述。對於 xterm-256color,它會列印:

xterm with 256 colors

infocmp -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):

  1. $TERMINFO(如果已設定)。只會搜尋該目錄。
  2. $HOME/.terminfo。
  3. $TERMINFO_DIRS 中列出的每個目錄。
  4. 編譯時內建的位置。在 Debian 和 Ubuntu 上,包含 /etc/terminfo、/lib/terminfo 和 /usr/share/terminfo。

在伺服器上執行 infocmp -D,列出該伺服器所使用的 ncurses 建置版本的搜尋目錄,不要直接依賴上述路徑。關鍵在第 2 步。系統會先搜尋您的家目錄,再搜尋任何系統目錄。因此,在 ~/.terminfo 下放置一個檔案,就能修正您帳戶的查找結果,不需要安裝套件,也不需要 root。

修正 1:使用伺服器已知的 TERM

最快的暫時解法,是為單一連線指定其他 terminal:

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,這個方法仍然有效。

代價是會失去 terminal 除了純 xterm-256color 之外所描述的所有功能。這包括透過 RGB capability 宣告的 24 位元色彩,以及透過 Smulx 提供樣式的底線。程式無法再看見這些 capability,因此會退回使用 256 色和一般底線。畫面仍可正常使用,只是功能不如原本選用的 terminal。

不要在伺服器的 .bashrc 中加入 export TERM=xterm-256color 來解決這個問題。該檔案會套用到每個連線,包括來自伺服器已知 terminal 的連線,因此會讓原本正常的工作階段降級。請將覆寫設定保留在用戶端,因為你知道該端執行的是哪個 terminal。

修正 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 ~/.terminfo

tput longname列印終端機描述,表示查找已成功;ls則會顯示編譯後的檔案位於以終端機名稱首字母命名的子目錄中。接著執行 top,或使用 watch -n1 uptime 監控;它會透過相同的函式庫重新繪製畫面,確認實際的 curses 程式能正確繪製畫面。

代價是:每台伺服器都要執行一次,而且該項目只存在某台機器上某個帳號的家目錄中。VPS 重建後,項目就會消失。將此命令加入你用來一次佈建及管理多台伺服器的工具中,讓新主機建立後就已完成項目編譯。

修正 3:安裝擴充 terminfo 資料庫

如果你具備 root 權限,且希望所有帳號都能解析此名稱:

sudo apt update
sudo apt install ncurses-term
tput -T xterm-ghostty longname

ncurses-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 可用來檢查:項目存在時會輸出描述;不存在時則會以結束狀態 3 輸出 unknown terminal。

若不想安裝整個套件,而只想在全系統安裝單一項目,請先複製來源檔,再以 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 會配置 pseudo terminal,讓 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 integration(ssh-env 和 ssh-terminfo),以及可自動完成兩項修正的 +ssh action。

這些輔助工具執行的命令,與剛才手動執行的命令相同。仍然需要了解手動寫法,因為連線若是從其他位置開始,例如 jump host 或 script 內,輔助工具就無法執行。

錯誤再次出現時

在 sudo -i 下。 以 root 身分啟動的 login 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 為核心的 終端機工作台 會掩蓋這個問題,直到您在尚未修正的主機上 attach 為止。

在新的伺服器上。 ~/.terminfo 是每個帳號與每台機器各自獨立的設定,因此重建後的 VPS 又會從空白狀態開始。

畫面正常,但按鍵行為異常。 如果畫面顯示正常,但 Home、End 或功能鍵會插入多餘字元,表示解析出的名稱對應到與您的終端機不相符的項目。按鍵序列與畫面繪製功能來自同一個 terminfo 項目,因此近似項目只能提供近似的按鍵行為。這通常是修正 1 在按鍵序列不同於 xterm 的模擬器上造成的結果。修正 2 才是正確解法,因為只有您模擬器的實際項目包含正確的按鍵序列。

FAQ

為什麼我透過 SSH 連線時只看到「unknown terminal type」?

因為必須包含終端機項目的資料庫位於伺服器上。終端機模擬器會將自身的描述安裝在執行它的電腦上,因此本機程式可以直接找到,不需要你額外處理。SSH 只會傳送 TERM 的值,因為通訊協定會在 pseudo-terminal 請求中攜帶該名稱。遠端 ncurses 會在遠端資料庫中查詢這個名稱,但找不到對應項目,因此 initscr 失敗,程式也會停止。

沒有伺服器上的 root 權限時,可以修正這個問題嗎?

可以。ncurses 會先搜尋 $HOME/.terminfo,再搜尋任何系統目錄,因此只要在該位置建立項目,就足以供你的帳號使用。每台伺服器執行一次 infocmp -x | ssh user@host -- tic -x -。如果無法寫入系統路徑,tic 會寫入你的 home directory;對沒有特權的帳號而言,這是正常情況。登入後執行 tput longname,確認查詢現在可以解析該項目。

為主機設定 TERM=xterm-256color 會失去哪些功能?

你的終端機模擬器所描述、但 xterm-256color 項目沒有的所有功能,例如透過 RGB 提供的 24-bit 色彩,以及透過 Smulx 提供的樣式底線。程式無法看到這些功能,因此會使用最接近的替代方案。功能鍵的控制序列也可能與實際終端機不同。請將設定放在用戶端的 ~/.ssh/config,不要放在伺服器上的 .bashrc,否則會讓原本已能正常運作的終端機連線也降級。

為什麼執行 sudo -i 後錯誤又出現?

sudo -i 會以 root 身分並搭配 HOME=/root 啟動 login shell,同時保留你的 TERM 值。接著 ncurses 會搜尋 /root/.terminfo,而不是你自己的 home directory,但找不到任何項目,因此 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(ncurses-bin 6.4+20240113-1ubuntu2.1,截至 August 2026),而 Ghostty 的項目是在 ncurses 6.5-20241228 中由上游加入,因此該套件不可能包含它。依賴該套件前,先使用 tput -T <name> longname 檢查;如果檢查結果仍顯示 unknown terminal,請自行提供該項目。

#terminfo#ssh#ncurses#tput#terminal