SSH मधील unknown terminal type त्रुटी कशी दुरुस्त करावी
SSH मध्ये "unknown terminal type" दिसत असल्यास server ला तुमचे TERM नाव माहीत नसते. root शिवाय home directory मधील terminfo entry compile करून curses प्रोग्राम सुरू करा.
"unknown terminal type" याचा अर्थ
SSH द्वारे दिसणाऱ्या "unknown terminal type" त्रुटीचा अर्थ असा आहे की TERM मधील नावाला server वरील terminfo database मध्ये जुळणारी entry नाही. तुमचा emulator तुमच्या laptop वर हे नाव सेट करतो. ते नाव ओळखणारा database remote machine वर असणे आवश्यक आहे. शोध अयशस्वी झाल्यावर त्या server वरील प्रत्येक curses प्रोग्राम काहीही प्रदर्शित करण्यापूर्वी थांबतो, कारण तुमचा terminal कोणत्या क्षमता पुरवतो याचे वर्णन त्याच्याकडे नसते.
तुमच्या emulator ची सर्व वैशिष्ट्ये कायम ठेवण्यासाठी उपाय एकाच command मध्ये आहे: तुमची स्वतःची terminfo entry server वरील ~/.terminfo मध्ये compile करा. ncurses कोणत्याही system directory आधी तुमची home directory शोधते. त्यामुळे root ची गरज नाही आणि इतर users मध्ये कोणताही बदल होत नाही.
TERM हे एक नाव आहे, तर terminfo हा डेटाबेस आहे
TERM मध्ये एक string असतो आणि तो string केवळ एक key असतो. terminfo हा terminal descriptions चा compiled database आहे. योग्य description शोधण्यासाठी प्रोग्राम ही key वापरतो. Description मध्ये terminal मध्ये किती colours आहेत, cursor ला row 12 column 40 वर नेण्यासाठी कोणते bytes पाठवायचे, F5 key कोणते bytes पाठवते आणि styled underline काढता येते का, याची नोंद असते. Linux वरील जवळपास प्रत्येक text user interface ज्या ncurses library वर आधारित असतो, ती startup वेळी ही description वाचते. top, less, nano आणि watch सारखे प्रोग्राम तिच्याशिवाय एकही screen दाखवू शकत नाहीत.
तुमची स्वतःची entry पाहा:
echo "$TERM"
tput longname
infocmp -1 | head -20tput longname, TERM ने निर्दिष्ट केलेल्या कोणत्याही TERM ची मानवी-वाचनीय description दाखवते. xterm-256color साठी ती अशी दिसते:
xterm with 256 colorsinfocmp -1 संपूर्ण entry decompile करते आणि प्रत्येक capability स्वतंत्र ओळीवर दाखवते. दोन्ही commands यशस्वी झाल्यास, या मशीनवरील database ला हे terminal माहीत आहे. SSH connection च्या दुसऱ्या बाजूलाही तुम्हाला हीच स्थिती आवश्यक आहे.
SSH वरच हे का बिघडते
SSH टर्मिनलचे नाव पाठवतो; त्यासोबत टर्मिनलचे वर्णन पाठवत नाही. Client pseudo terminal मागतो तेव्हा TERM त्या विनंतीसोबत पाठवले जाते. OpenSSH manual मध्ये हे स्पष्टपणे नमूद केले आहे: "pseudo-terminal मागितले जाते तेव्हा TERM environment variable नेहमी पाठवले जाते, कारण protocol साठी ते आवश्यक आहे". त्यामुळे VPS वरील login shell ला TERM=xterm-ghostty, xterm-kitty किंवा तुमचा emulator वापरत असलेले दुसरे नाव मिळते. त्या नावामागील वर्णन तुमच्या laptop वर, त्याच्या database मध्येच राहते. तुमचा emulator अस्तित्वात येण्यापूर्वी तयार केलेल्या server ने ते नाव कधीही ऐकलेले नसते. SSH connection मध्येच terminal descriptions प्रतिकृत करणारी कोणतीही यंत्रणा नाही. हे जाणीवपूर्वक असे आहे: protocol मध्ये नाव पाठवले जाते, capabilities ची संपूर्ण माहिती नाही.
तुमच्या स्वतःच्या machine वर निश्चितपणे अस्तित्वात नसलेले नाव वापरून ही त्रुटी पुन्हा निर्माण करा:
TERM=xterm-nosuchthing tput colors
echo "$?"tput: unknown terminal "xterm-nosuchthing"Exit status 3 आहे. ncurses मध्ये याचे वर्णन अज्ञात terminal type किंवा गहाळ database असे केले आहे. प्रत्येक curses program समान lookup करतो. त्यामुळे एकच नाव गहाळ असल्यास, त्या सर्वांच्या मागे एकच कारण असूनही प्रत्येक program वेगळा संदेश दाखवतो. nano ला Error opening terminal: xterm-nosuchthing. मिळाल्यावर प्रक्रिया थांबते. startup वेळी description load करता न आल्यास ncurses कडून ही प्रमाणित त्रुटी दिली जाते. vim, E558: Terminal entry not found in terminfo छापते. less, WARNING: terminal is not fully functional छापते. अंशतः चालणारा pager आणि सुरू होण्यास नकार देणारा editor या परस्पर असंबंधित त्रुटी वाटू शकतात. प्रत्यक्षात दोन्हींचे कारण एकच गहाळ file आहे.
ncurses entry कुठे शोधते
ncurses दिलेल्या निश्चित क्रमाने शोध घेते. हा क्रम terminfo(5) मध्ये दस्तऐवजीकरण केलेला आहे:
$TERMINFOसेट असल्यास ते. फक्त याच directory मध्ये शोध घेतला जातो.$HOME/.terminfo.$TERMINFO_DIRSमध्ये सूचीबद्ध केलेली प्रत्येक directory.- compile केलेली ठिकाणे. Debian आणि Ubuntu मध्ये यामध्ये
/etc/terminfo,/lib/terminfoआणि/usr/share/terminfoसमाविष्ट आहेत.
वर दिलेल्या paths वर अवलंबून न राहता, त्या server वरील ncurses build वापरत असलेल्या directories ची यादी दाखवण्यासाठी infocmp -D चालवा. संपूर्ण युक्ती Step 2 मध्ये आहे. तुमची home directory कोणत्याही system directory आधी शोधली जाते. त्यामुळे ~/.terminfo अंतर्गत ठेवलेली एक file तुमच्या account साठी lookup दुरुस्त करते. यासाठी package install किंवा root आवश्यक नाही.
उपाय 1: सर्व्हरला आधीपासून माहीत असलेले TERM वापरा
एका कनेक्शनसाठी वेगळ्या terminal चे नाव देणे हा अडथळा दूर करण्याचा सर्वात जलद मार्ग आहे:
TERM=xterm-256color ssh user@203.0.113.10तुमच्या laptop वरील ~/.ssh/config मध्ये त्या host साठी हे कायमस्वरूपी सेट करा:
Host vps1
HostName 203.0.113.10
User deploy
SetEnv TERM=xterm-256colorSetEnv साठी client वर OpenSSH 7.8 किंवा त्यानंतरचे version आवश्यक आहे. हे version August 2018 मध्ये release झाले. TERM हे असे एकमेव variable आहे ज्यासाठी server ची परवानगी आवश्यक नाही. Manual मध्ये म्हटले आहे: "Similarly to SendEnv, with the exception of the TERM variable, the server must be prepared to accept the environment variable". त्यामुळे AcceptEnv line अजिबात नसलेल्या hardened sshd विरुद्धही हे कार्य करते.
याची किंमत काय आहे: plain xterm-256color पलीकडे तुमचा emulator ज्या सर्व capability जाहीर करतो त्या उपलब्ध राहत नाहीत. यात RGB capability द्वारे जाहीर केलेला 24-bit colour आणि Smulx द्वारे styled केलेले underlines यांचा समावेश आहे. Programs ना या capability दिसत नाहीत. त्यामुळे ते 256 colours आणि साध्या underline वर परततात. Screen कार्यरत राहते. तुम्ही निवडलेल्या terminal च्या तुलनेत त्याची क्षमता मात्र कमी असते.
Server वरील तुमच्या .bashrc मध्ये export TERM=xterm-256color जोडून ही समस्या सोडवू नका. ही file प्रत्येक connection साठी चालते. यात server ला माहीत असलेल्या terminal नावावरून आलेल्या connections चादेखील समावेश होतो. त्यामुळे आधीपासून योग्य असलेल्या sessions ची क्षमता कमी होते. Override client वरच ठेवा. त्यामुळे तुम्ही कोणता emulator चालवत आहात हे त्याला माहीत असते.
Fix 2: तुमची terminfo entry सर्व्हरवर एकदाच पाठवा
हा उपाय तुमचा emulator जसाच्या तसा ठेवतो. Entry स्थानिक पातळीवर decompile करा, ती SSH द्वारे pipe करा आणि दूरस्थ सर्व्हरवर compile करा:
infocmp -x | ssh user@203.0.113.10 -- tic -x -infocmp -x तुमच्या सध्याच्या TERM साठीची entry source text म्हणून दाखवते. यात extended (user-defined) capabilities देखील असतात. tic -x ही source पुन्हा सर्व्हरवर binary description मध्ये compile करते. दोन्ही बाजूंवरील -x महत्त्वाचे आहे. ते नसल्यास Smulx सारख्या capabilities मार्गातच गाळल्या जातात आणि तुमच्या terminal ची downgraded copy सर्व्हरवर पाठवली जाते.
tic शक्य असल्यास system directory मध्ये लिहिते. तेथे user ला write access नसल्यास ती $HOME/.terminfo वर fallback करते. VPS वरील सामान्य account ला home directory मिळते, आणि येथे तेच अपेक्षित आहे. तुम्ही destination देखील स्पष्टपणे देऊ शकता:
infocmp -x | ssh user@203.0.113.10 -- tic -x -o '~/.terminfo' /dev/stdin~/.terminfo भोवतीचे quotes केवळ सजावटीसाठी नाहीत. ssh command words एकाच string मध्ये जोडते आणि ती remote shell कडे देते. त्यामुळे unquoted ~ आधी तुमच्या local shell कडून expand होते. त्यानंतर तुम्ही /home/yourname/.terminfo हा literal पाठवता, पण दूरस्थ मशीनवरील account चे नाव वेगळे असू शकते. tic permission error सह अपयशी ठरते किंवा अशा path मध्ये लिहिते जिथे ncurses कधीही शोध घेत नाही. Tilde ला quote करा; remote shell त्याचा विस्तार करेल.
Login करा आणि तपासा:
ssh user@203.0.113.10
tput longname
ls -R ~/.terminfotput longname तुमच्या terminal चे description छापते, याचा अर्थ lookup आता यशस्वी होतो. ls compiled file terminal name च्या पहिल्या अक्षराच्या नावाच्या subdirectory अंतर्गत दाखवते. त्यानंतर top चालवा किंवा watch -n1 uptime, जे त्याच library द्वारे screen पुन्हा draw करते, जेणेकरून एखादा प्रत्यक्ष curses program screen योग्य प्रकारे दाखवतो याची खात्री करता येईल.
यासाठीचा खर्च: प्रत्येक सर्व्हरसाठी एकदा ही पायरी करावी लागते. तसेच entry एका मशीनवरील एका account च्या home directory मध्ये राहते. VPS पुन्हा build केल्यास ती नष्ट होते. अनेक सर्व्हर एकाच वेळी provision आणि manage करण्यासाठी तुम्ही वापरत असलेल्या साधनामध्ये हा command समाविष्ट करा. त्यामुळे नवीन host वर entry आधीच compiled अवस्थेत उपलब्ध असेल.
दुरुस्ती 3: extended terminfo database स्थापित करा
तुमच्याकडे root प्रवेश असल्यास आणि या सर्व्हरवरील प्रत्येक account साठी हे नाव resolve व्हावे असे असल्यास:
sudo apt update
sudo apt install ncurses-term
tput -T xterm-ghostty longnamencurses-term मध्ये base install मधून वगळलेली terminal descriptions असतात. यामुळे root आणि इतर प्रत्येक user साठी हे नाव उपलब्ध होते; fix 2 मध्ये असे होत नाही.
तुमच्या terminal ची entry तुमच्या distribution ने package केलेल्या ncurses release मध्ये अस्तित्वात असेल तरच याचा उपयोग होतो. त्यामुळे गृहीत न धरता आधी तपासा. Ubuntu 24.04 मध्ये (August 2026 पर्यंत) ncurses-bin 6.4+20240113-1ubuntu2.1 उपलब्ध आहे. Ghostty ची entry upstream मध्ये ncurses 6.5-20241228 मध्ये जोडली गेली. ही आवृत्ती त्यापेक्षा नवीन आहे. त्यामुळे Ubuntu 24.04 वरील apt install ncurses-term कितीही वेळा चालवले तरी xterm-ghostty entry तयार करू शकत नाही. tput -T <name> longname ही तपासणी करण्यासाठीची command आहे: entry उपलब्ध असल्यास ती description दाखवते आणि entry उपलब्ध नसल्यास exit status 3 सह unknown terminal दाखवते.
संपूर्ण package ऐवजी एकच entry system-wide स्थापित करण्यासाठी source copy करा आणि root म्हणून compile करा:
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दुसऱ्या command मधील -t pseudo terminal allocate करते. त्यामुळे sudo password साठी prompt दाखवू शकते. ते नसल्यास sudo कदाचित sudo: no tty present and no askpass program specified सह exit होईल.
Emulator ला transfer करू द्या
काही emulators मध्ये fix 2 आपोआप करणारा helper असतो. kitty मध्ये ssh kitten आहे: kitten ssh myserver कनेक्ट होते आणि kitty चे terminfo remote host वर आपोआप कॉपी करते. त्याच्या documentation मध्ये manual form infocmp -a xterm-kitty | ssh myserver tic -x -o \~/.terminfo /dev/stdin देखील दिला आहे. वर वर्णन केलेल्या कारणासाठी त्यात tilde escape केलेला आहे. Ghostty मध्ये infocmp -x xterm-ghostty | ssh YOUR-SERVER -- tic -x - documented आहे. त्यासोबत shell integration (ssh-env आणि ssh-terminfo) तसेच दोन्ही fixes आपोआप करणारी +ssh action दिली आहे.
हे helpers तुम्ही नुकतेच manually चालवलेले तेच commands चालवतात. तरीही manual form माहित असणे महत्त्वाचे आहे, कारण connection दुसऱ्या ठिकाणाहून, jump host वरून किंवा script मध्ये सुरू झाल्यास helper काम करू शकत नाही.
त्रुटी पुन्हा आल्यावर
sudo -i अंतर्गत. root म्हणून login shell मध्ये HOME=/root आहे आणि sudo तुमचे TERM ठेवते. ncurses आता /root/.terminfo मध्ये शोध घेते. त्या ठिकाणी तुमची entry नसल्यामुळे ही त्रुटी फक्त root साठी पुन्हा येते. sudo -i env ने याची खात्री करा आणि HOME व TERM ओळी वाचा. ही entry system directory मध्ये install करा किंवा तिची प्रत /root/.terminfo मध्ये ठेवा.
tmux किंवा screen मध्ये. या दोन्ही साधनांमध्ये त्यांच्यात चालणाऱ्या प्रोग्रामसाठी स्वतंत्र TERM सेट केला जातो. तो सामान्यतः screen-256color किंवा tmux-256color असतो. जुन्या server ला screen-256color माहीत असते, पण tmux-256color माहीत नसू शकते. त्यामुळे बाहेरील shell व्यवस्थित असतो, पण session मधील सर्वकाही अयशस्वी होते. कारण तेच आहे; नाव वेगळे आहे. Server वर tput -T tmux-256color longname चालवून त्यापैकी कोणते उपलब्ध आहे ते पहा. tmux वर आधारित terminal workbench याकडे तुमचे लक्ष जाऊ देत नाही. ज्या host वर ही समस्या अद्याप दुरुस्त केलेली नाही, त्याला attach करेपर्यंत हे समजत नाही.
नवीन server वर. ~/.terminfo हे प्रत्येक account आणि प्रत्येक machine साठी स्वतंत्र असते. त्यामुळे पुन्हा तयार केलेला VPS पुन्हा रिकाम्यापासून सुरू होतो.
स्क्रीनवरील रेखाटन योग्य आहे, पण कळा चुकीच्या प्रकारे काम करतात. Display व्यवस्थित दिसत असेल, पण Home, End किंवा function keys अनावश्यक अक्षरे टाकत असतील, तर नाव अशा entry कडे resolve झाले आहे जी तुमच्या terminal शी जुळत नाही. Drawing capabilities प्रमाणेच key sequences देखील त्याच terminfo entry मधून येतात. त्यामुळे अंदाजे entry मुळे key sequences देखील अंदाजे मिळतात. xterm पेक्षा वेगळे key sequences असलेल्या emulator वर fix 1 केल्यास हा नेहमीचा परिणाम दिसतो. यासाठी fix 2 वापरा, कारण फक्त तुमच्या emulator ची वास्तविक entry योग्य key sequences ठेवते.
FAQ
SSH वर "unknown terminal type" असे का दिसते?
तुमच्या terminal च्या entry साठी आवश्यक database सर्व्हरवर असते. तुमचा emulator त्याचे वर्णन ज्या मशीनवर चालतो तिथे install करतो, त्यामुळे स्थानिक प्रोग्राम्सना ते तुमच्या कोणत्याही अतिरिक्त कृतीशिवाय सापडते. SSH फक्त TERM ची value पाठवतो, कारण pseudo-terminal request सोबत protocol हे नाव पाठवतो. Remote ncurses हे नाव remote database मध्ये शोधते, पण तेथे काहीही सापडत नाही. त्यामुळे initscr fail होते आणि प्रोग्राम थांबतो.
सर्व्हरवर root access नसताना हे दुरुस्त करता येईल का?
होय. ncurses कोणत्याही system directory च्या आधी $HOME/.terminfo मध्ये शोधते, त्यामुळे तुमच्या account साठी तेथे असलेली entry पुरेशी असते. प्रत्येक server साठी infocmp -x | ssh user@host -- tic -x - एकदा चालवा. System path मध्ये लिहिता येत नसल्यास tic तुमच्या home directory मध्ये लिहिते. Unprivileged account साठी हीच सामान्य स्थिती आहे. Login करून lookup आता resolve होत आहे का हे तपासण्यासाठी tput longname चालवा.
एखाद्या host साठी TERM=xterm-256color सेट केल्यावर काय गमावले जाते?
तुमचा emulator xterm-256color entry पेक्षा अधिक ज्या capabilities चे वर्णन करतो त्या सर्व, जसे RGB द्वारे 24-bit colour आणि Smulx द्वारे styled underlines. प्रोग्राम्सना या capabilities दिसत नाहीत, त्यामुळे ते सर्वात जवळचा fallback वापरतात. Function-key sequences तुमच्या प्रत्यक्ष terminal पेक्षा वेगळेही असू शकतात. ही setting server वरील .bashrc मध्ये ठेवण्याऐवजी client वरील ~/.ssh/config मध्ये ठेवा. अन्यथा आधीपासून कार्यरत terminals मधील sessions देखील downgrade होतील.
sudo -i नंतर ही error पुन्हा का येते?
sudo -i HOME=/root सह root म्हणून login shell सुरू करते आणि तुमची TERM value कायम ठेवते. त्यानंतर ncurses तुमच्या स्वतःच्या home directory ऐवजी /root/.terminfo मध्ये शोधते. तेथे काहीही सापडत नाही, त्यामुळे root ला तुमच्या account ला आता न दिसणारी तीच failure दिसते. sudo -i env चालवून HOME आणि TERM lines तपासा. sudo tic -x -o /usr/share/terminfo वापरून entry system directory मध्ये compile करा किंवा ती /root/.terminfo मध्ये copy करा.
apt install ncurses-term ने ही समस्या नेहमी दुरुस्त होते का?
नाही. तुमच्या distribution ने package केलेल्या ncurses release मध्ये ज्या entries अस्तित्वात होत्या त्याच ते add करते. Ubuntu 24.04 मध्ये ncurses 6.4 येते (ncurses-bin 6.4+20240113-1ubuntu2.1, August 2026 पर्यंत), तर Ghostty ची entry upstream ncurses 6.5-20241228 मध्ये add करण्यात आली. त्यामुळे त्या package मध्ये ती entry असू शकत नाही. Package वर अवलंबून राहण्यापूर्वी tput -T <name> longname वापरून तपासा. तपासणीत अजूनही unknown terminal दिसत असल्यास entry स्वतः install करा.