如何修正 SSH 的 unknown terminal type 錯誤
SSH 傳送的 TERM 名稱若不在伺服器 terminfo 資料庫中,curses 程式就會失敗。將 terminfo 編譯到家目錄即可修正,無需 root 權限。
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 -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
最快的暫時解法,是為單一連線指定其他 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 ~/.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 可用來檢查:項目存在時會輸出描述;不存在時則會以結束狀態 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,請自行提供該項目。