SSD Nodes Learn 🎉 VPS dari $5.50/bln
Panduan Matt ConnorOleh Matt Connor

Cara Selesai Ralat 'unknown terminal type' SSH

Ralat unknown terminal type berlaku apabila pelayan tidak mengenali tetapan TERM anda. Selesaikan isu ini tanpa akses root dengan memuat naik entri terminfo ke direktori rumah.

Apakah maksud "unknown terminal type"

Ralat unknown terminal type melalui SSH bermaksud nama dalam TERM tidak mempunyai entri yang sepadan dalam pangkalan data terminfo pada pelayan. Emulator anda menetapkan nama tersebut pada komputer riba anda. Pangkalan data yang perlu mengenal pastinya berada pada mesin jauh. Apabila carian gagal, setiap program curses pada pelayan tersebut berhenti sebelum ia melukis apa-apa, kerana ia tidak mempunyai deskripsi tentang keupayaan terminal anda.

Penyelesaian yang mengekalkan semua ciri emulator anda ialah satu arahan: kompil entri terminfo anda sendiri ke dalam ~/.terminfo pada pelayan. ncurses mencari direktori rumah anda sebelum mana-mana direktori sistem, jadi ini tidak memerlukan root dan tidak mengubah apa-apa untuk pengguna lain.

TERM ialah satu nama, manakala terminfo ialah pangkalan datanya

TERM menyimpan satu rentetan, dan rentetan itu hanyalah satu kunci. terminfo ialah pangkalan data yang telah dikompil bagi deskripsi terminal, dan kunci tersebut merupakan cara program mencari deskripsi yang tepat. Sesuatu deskripsi merekodkan bilangan warna yang dimiliki oleh terminal, bait yang menggerakkan kursor ke baris 12 lajur 40, bait yang dihantar oleh kekunci F5, serta sama ada terminal tersebut boleh melukis garis bawah bergaya. ncurses, iaitu pustaka yang menjadi asas kepada hampir setiap antara muka pengguna teks pada Linux, membaca deskripsi tersebut semasa permulaan. Program seperti top, less, nano dan watch tidak dapat memaparkan satu skrin pun tanpanya.

Lihat entri anda sendiri:

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

tput longname mencetak deskripsi yang boleh dibaca manusia bagi apa sahaja yang dinamakan oleh TERM. Bagi xterm-256color, ia mencetak:

xterm with 256 colors

infocmp -1 menyahkompil keseluruhan entri dan mencetak satu keupayaan bagi setiap baris. Jika kedua-dua arahan berfungsi, pangkalan data pada mesin ini mengenali terminal ini. Itulah keadaan yang anda perlukan pada bahagian hujung sambungan SSH juga.

Mengapa ia hanya tergendala melalui SSH

SSH hanya menghantar nama dan tiada maklumat lain. Apabila klien meminta pseudo terminal, TERM akan dihantar bersama permintaan tersebut. Manual OpenSSH menyatakan dengan jelas: "pemboleh ubah persekitaran TERM sentiasa dihantar apabila pseudo-terminal diminta kerana ia diperlukan oleh protokol". Jadi, shell log masuk anda pada VPS menerima TERM=xterm-ghostty, atau xterm-kitty, atau apa jua nama yang digunakan oleh emulator anda. Deskripsi di sebalik nama tersebut kekal pada komputer riba anda, dalam pangkalan data komputer riba anda. Pelayan yang dibina sebelum emulator anda wujud tidak pernah mengenali nama tersebut. Tiada apa-apa dalam sambungan SSH itu sendiri yang menyalin deskripsi terminal, dan ini adalah disengajakan: protokol tersebut membawa nama, bukan himpunan keupayaan.

Ulangi kegagalan tersebut pada mesin anda sendiri dengan nama yang sememangnya tidak wujud:

TERM=xterm-nosuchthing tput colors
echo "$?"
tput: unknown terminal "xterm-nosuchthing"

Status keluar adalah 3, yang didokumentasikan oleh ncurses sebagai jenis terminal yang tidak diketahui atau pangkalan data yang hilang. Setiap program curses menjalankan carian yang sama, jadi satu nama yang hilang menghasilkan mesej yang berbeza daripada setiap program dengan punca tunggal di sebalik kesemuanya. nano berhenti dengan Error opening terminal: xterm-nosuchthing., kegagalan ncurses standard apabila ia tidak dapat memuatkan deskripsi semasa permulaan. vim mencetak E558: Terminal entry not found in terminfo. less mencetak WARNING: terminal is not fully functional. Pager yang berfungsi separuh jalan dan editor yang enggan bermula kelihatan seperti pepijat yang tidak berkaitan. Ia adalah fail hilang yang sama.

Lokasi carian entri oleh ncurses

ncurses melakukan carian mengikut urutan tetap yang didokumentasikan dalam terminfo(5):

  1. $TERMINFO, jika ia ditetapkan. Hanya direktori tersebut yang akan dicari.
  2. $HOME/.terminfo.
  3. setiap direktori yang disenaraikan dalam $TERMINFO_DIRS.
  4. lokasi yang dikompilasi masuk, yang pada Debian dan Ubuntu merangkumi /etc/terminfo, /lib/terminfo dan /usr/share/terminfo.

Jalankan infocmp -D pada pelayan untuk mencetak senarai yang digunakan oleh binaan ncurses tersebut, daripada mempercayai laluan di atas. Langkah 2 adalah kunci penyelesaiannya. Direktori rumah anda dicari sebelum mana-mana direktori sistem, jadi satu fail di bawah ~/.terminfo akan membetulkan carian untuk akaun anda tanpa perlu memasang pakej dan tanpa akses root.

Pembaikan 1: gunakan TERM yang sudah dikenali oleh pelayan

Cara terpantas untuk menyahsekat adalah dengan menamakan terminal yang berbeza untuk satu sambungan:

TERM=xterm-256color ssh user@203.0.113.10

Jadikannya kekal untuk hos tersebut dalam ~/.ssh/config pada komputer riba anda:

Host vps1
    HostName 203.0.113.10
    User deploy
    SetEnv TERM=xterm-256color

SetEnv memerlukan OpenSSH 7.8 atau lebih baharu pada klien, yang dikeluarkan pada Ogos 2018. TERM ialah satu-satunya pemboleh ubah yang tidak memerlukan kebenaran pelayan: manual menyatakan "Sama seperti SendEnv, dengan pengecualian pemboleh ubah TERM, pelayan mesti bersedia untuk menerima pemboleh ubah persekitaran". Jadi, ini berfungsi walaupun terhadap sshd yang diperkukuh tanpa sebarang baris AcceptEnv.

Kosnya: segala-galanya yang diterangkan oleh emulator anda selain daripada xterm-256color biasa. Ini termasuk warna 24-bit yang diiklankan melalui keupayaan RGB dan garis bawah bergaya melalui Smulx. Program tidak lagi dapat melihat keupayaan tersebut, jadi ia kembali kepada 256 warna dan garis bawah biasa. Skrin berfungsi. Ia hanya kurang berkeupayaan berbanding terminal yang anda pilih.

Jangan selesaikan masalah ini dengan menambah export TERM=xterm-256color ke dalam .bashrc anda pada pelayan. Fail itu berjalan untuk setiap sambungan, termasuk sambungan daripada terminal yang namanya sudah dikenali oleh pelayan, jadi ia menurunkan taraf sesi yang sebenarnya sudah baik. Kekalkan penggantian (override) pada klien, di mana anda tahu emulator mana yang anda jalankan.

Pembaikan 2: hantar entri terminfo anda ke pelayan sekali sahaja

Ini adalah pembaikan yang mengekalkan emulator anda dalam keadaan asal. Nyahkompil entri tersebut secara setempat, salurkan melalui SSH, dan kompil ia di bahagian pelayan:

infocmp -x | ssh user@203.0.113.10 -- tic -x -

infocmp -x mencetak entri untuk TERM semasa anda sebagai teks sumber, termasuk keupayaan lanjutan (yang ditakrifkan pengguna). tic -x mengkompil semula sumber tersebut menjadi deskripsi binari di pelayan. -x pada kedua-dua belah pihak adalah penting, kerana tanpanya keupayaan seperti Smulx akan digugurkan semasa transit dan anda menghantar salinan terminal anda yang telah diturun taraf.

tic menulis ke dalam direktori sistem apabila ia boleh, dan kembali kepada $HOME/.terminfo apabila pengguna tidak mempunyai akses tulis di sana. Akaun biasa pada VPS akan mendapat direktori rumah, yang merupakan apa yang anda mahukan. Anda juga boleh menamakan destinasi:

infocmp -x | ssh user@203.0.113.10 -- tic -x -o '~/.terminfo' /dev/stdin

Tanda petikan di sekeliling ~/.terminfo bukan sekadar hiasan. ssh mencantumkan perkataan arahan menjadi satu rentetan dan menyerahkannya kepada shell jauh, jadi ~ yang tidak bertanda petikan akan dikembangkan oleh shell setempat anda terlebih dahulu. Anda kemudian menghantar /home/yourname/.terminfo literal ke mesin di mana akaun anda mungkin dipanggil dengan nama lain. tic akan gagal dengan ralat kebenaran, atau ia menulis ke dalam laluan yang tidak pernah dicari oleh ncurses. Letakkan tanda petikan pada tilde dan shell jauh akan mengembangkannya.

Log masuk dan semak:

ssh user@203.0.113.10
tput longname
ls -R ~/.terminfo

tput longname yang mencetak deskripsi terminal anda bermakna carian kini berjaya, dan ls menunjukkan fail yang telah dikompil di bawah subdirektori yang dinamakan mengikut huruf pertama nama terminal. Kemudian jalankan top, atau watch -n1 uptime, yang melukis semula melalui pustaka yang sama, untuk mengesahkan program curses sebenar memaparkan skrin.

Kosnya: satu langkah bagi setiap pelayan, dan entri tersebut kekal dalam direktori rumah satu akaun pada satu mesin. Bina semula VPS dan ia akan hilang. Masukkan arahan tersebut ke dalam apa sahaja yang anda gunakan untuk memperuntukkan dan mengurus beberapa pelayan serentak supaya hos baharu tiba dengan entri yang telah dikompil.

Pembaikan 3: pasang pangkalan data terminfo lanjutan

Jika anda mempunyai akses root dan mahu nama tersebut diselesaikan untuk setiap akaun pada mesin tersebut:

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

ncurses-term menyimpan deskripsi terminal yang tidak disertakan dalam pemasangan asas. Ia membetulkan nama untuk root dan bagi setiap pengguna lain, sesuatu yang tidak dilakukan oleh pembaikan 2.

Ia hanya membantu apabila entri terminal anda wujud dalam keluaran ncurses yang dibungkus oleh pengedaran anda, jadi semak dahulu dan jangan terus membuat andaian. Ubuntu 24.04 membekalkan ncurses-bin 6.4+20240113-1ubuntu2.1 (sehingga Ogos 2026). Entri Ghostty telah ditambah dalam ncurses 6.5-20241228, yang lebih baharu, jadi apt install ncurses-term pada Ubuntu 24.04 tidak dapat menghasilkan entri xterm-ghostty tidak kira berapa kerap anda menjalankannya. tput -T <name> longname ialah cara semakan: ia mencetak deskripsi apabila entri tersebut hadir, dan unknown terminal dengan status keluar 3 apabila ia tidak hadir.

Untuk memasang satu entri secara menyeluruh pada sistem dan bukannya keseluruhan pakej, salin sumber tersebut dan kompil ia sebagai 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 pada arahan kedua memperuntukkan terminal pseudo, supaya sudo boleh meminta kata laluan. Tanpanya, sudo mungkin keluar dengan sudo: no tty present and no askpass program specified.

Biarkan emulator melakukan pemindahan

Sesetengah emulator menyertakan pembantu yang melaksanakan pembaikan 2 untuk anda. kitty mempunyai ssh kitten: kitten ssh myserver menyambung dan menyalin terminfo kitty ke hos jauh secara automatik. Dokumentasinya juga memberikan bentuk manual, infocmp -a xterm-kitty | ssh myserver tic -x -o \~/.terminfo /dev/stdin, dengan tilde yang di-escape atas sebab yang diterangkan di atas. Ghostty mendokumentasikan infocmp -x xterm-ghostty | ssh YOUR-SERVER -- tic -x -, dan menyertakan integrasi shell (ssh-env dan ssh-terminfo) serta tindakan +ssh yang mengautomasikan kedua-dua pembaikan tersebut.

Pembantu ini menjalankan perintah yang sama seperti yang anda baru jalankan secara manual. Mengetahui bentuk manual tetap penting, kerana pembantu tidak boleh bertindak apabila sambungan bermula di tempat lain, pada jump host atau di dalam skrip.

Apabila ralat kembali berlaku

Di bawah sudo -i. Shell log masuk sebagai root mempunyai HOME=/root, dan sudo mengekalkan TERM anda. ncurses kini mencari /root/.terminfo, yang tidak mengandungi entri anda, jadi kegagalan berlaku untuk root sahaja. Sahkan dengan sudo -i env dan baca baris HOME serta TERM. Pasang entri tersebut ke dalam direktori sistem, atau letakkan salinan di /root/.terminfo.

Di dalam tmux atau screen. Ini menetapkan TERM sendiri untuk program yang berjalan di dalamnya, biasanya screen-256color atau tmux-256color. Pelayan yang lebih lama mengenali screen-256color dan mungkin tidak mengenali tmux-256color, jadi shell luaran berfungsi dengan baik manakala segala-galanya di dalam sesi tersebut gagal. Punca yang sama, nama yang berbeza. Jalankan tput -T tmux-256color longname pada pelayan untuk melihat yang mana satu antara kedua-duanya yang ada. Sebuah terminal workbench yang dibina di sekitar tmux menyembunyikan perkara ini sehingga hari anda menyambung pada hos yang belum anda baiki.

Pada pelayan baharu. ~/.terminfo adalah mengikut akaun dan mengikut mesin, jadi VPS yang dibina semula bermula dengan kosong semula.

Skrin memaparkan, kekunci tidak berfungsi dengan betul. Jika paparan baik tetapi Home, End atau kekunci fungsi memasukkan aksara yang tidak sepatutnya, nama tersebut diselesaikan kepada entri yang tidak sepadan dengan terminal anda. Jujukan kekunci datang daripada entri terminfo yang sama dengan keupayaan melukis, jadi entri yang hampir tepat memberikan kekunci yang hampir tepat. Itu adalah hasil biasa daripada pembaikan 1 pada emulator yang jujukan kekuncinya berbeza daripada xterm. Pembaikan 2 adalah jawapannya, kerana hanya entri sebenar emulator anda yang membawa jujukan yang betul.

FAQ

Mengapa saya hanya melihat "unknown terminal type" melalui SSH?

Ini kerana pangkalan data yang menyimpan entri terminal anda berada pada pelayan. Emulator anda memasang deskripsinya pada mesin tempat ia dijalankan, jadi program tempatan menemuinya tanpa sebarang usaha daripada anda. SSH hanya menghantar nilai TERM, memandangkan protokol tersebut membawa nama itu bersama permintaan pseudo-terminal. ncurses jauh mencari nama tersebut dalam pangkalan data jauh dan tidak menemui apa-apa, jadi initscr gagal dan program terhenti.

Bolehkah saya membaiki ini tanpa akses root pada pelayan?

Boleh. ncurses mencari $HOME/.terminfo sebelum mana-mana direktori sistem, jadi entri di situ sudah memadai untuk akaun anda. Jalankan infocmp -x | ssh user@host -- tic -x - sekali bagi setiap pelayan. tic menulis ke dalam direktori home anda apabila ia tidak dapat menulis ke laluan sistem, yang merupakan keadaan biasa bagi akaun tanpa keistimewaan. Log masuk dan jalankan tput longname untuk mengesahkan carian kini selesai.

Apa yang saya hilang dengan menetapkan TERM=xterm-256color untuk hos?

Setiap keupayaan yang diterangkan oleh emulator anda selain daripada entri xterm-256color, seperti warna 24-bit melalui RGB dan garis bawah bergaya melalui Smulx. Program tidak dapat melihat keupayaan tersebut, jadi ia menggunakan sandaran yang paling hampir. Jujukan kekunci fungsi juga mungkin berbeza daripada terminal sebenar anda. Letakkan tetapan tersebut pada klien dalam ~/.ssh/config dan bukannya dalam .bashrc pada pelayan, yang akan menurunkan taraf sesi daripada terminal yang sudah berfungsi.

Mengapa ralat kembali selepas sudo -i?

sudo -i memulakan shell log masuk sebagai root dengan HOME=/root, sambil mengekalkan nilai TERM anda. ncurses kemudian mencari /root/.terminfo dan bukannya direktori home anda sendiri dan tidak menemui apa-apa, jadi root melihat kegagalan yang sama yang tidak lagi dilihat oleh akaun anda. Jalankan sudo -i env dan semak baris HOME dan TERM. Kompil entri tersebut ke dalam direktori sistem dengan sudo tic -x -o /usr/share/terminfo, atau salin ke dalam /root/.terminfo.

Adakah apt install ncurses-term sentiasa membaikinya?

Tidak. Ia hanya menambah entri yang wujud dalam keluaran ncurses yang dibungkus oleh pengedaran anda. Ubuntu 24.04 menghantar ncurses 6.4 (ncurses-bin 6.4+20240113-1ubuntu2.1, setakat Ogos 2026), dan entri Ghostty telah ditambah dalam ncurses 6.5-20241228, jadi pakej tersebut tidak dapat memuatkannya. Semak dengan tput -T <name> longname sebelum bergantung pada pakej tersebut, dan hantar entri itu sendiri apabila semakan masih melaporkan terminal tidak diketahui.

#terminfo#ssh#ncurses#tput#terminal