/bin/bash,csh等是shell
xterm等是终端,$TERM
putty,terminator等是终端模拟器
xterm
is supposed to be a superset of vt220
, in other words it's like vt220
but has more features. For example, xterm
usually supports colors, but vt220
doesn't. You can test this by pressing z inside top
.
当前系统$TERM取值是 xterm,在top命令中输入z果然会变色
In the same way, vt220
has more features than vt100
. For example, vt100
doesn't seem to support F11 and F12.
Compare their features and escape sequences that your system thinks they have by running infocmp <term type 1> <term type 2>
, e.g. infocmp vt100 vt220
.
The full list varies from system to system. You should be able to get the list using toe
, toe /usr/share/terminfo
, or find ${TERMINFO:-/usr/share/terminfo}
. If none of those work, you could also look at ncurses' terminfo.src, which is where most distributions get the data from these days.
But unless your terminal looks like this or this, there's only a few others you might want to use:
xterm-color
- if you're on an older system and colors don't workputty
,konsole
,Eterm
,rxvt
,gnome
, etc. - if you're running an XTerm emulator and some of the function keys, Backspace, Delete, Home, and End don't work properlyscreen
- if running inside GNU screen (or tmux)linux
- when logging in via a Linux console (e.g. Ctrl+Alt+F1)dumb
- when everything is broken
ls /lib/terminfo/* /usr/share/terminfo/*
(these are the paths on Debian, other distributions may have slightly different paths). Most of them are highly exotic.
Run infocmp wihtout any argument will give you all available xterm alternatives:
$> infocmp
xterm|xterm-debian|X11 terminal emulator,
am, bce, km, mc5i, mir, msgr, npc, xenl,
colors#8, cols#80, it#8, lines#24, pairs#64,
...
For more info check
$> ls /lib/terminfo/x/
xterm xterm-256color xterm-color xterm-debian xterm-mono
xterm-r5 xterm-r6 xterm-vt220 xterm-xfree86
One big difference between an xterm, and a Virtual console is that an xterminal can be resized to different sizes. The console only have a fixed set of resulations. The TERM varable is being used for what it was designed for.
In lots of places, depending
On virtual terminals and real terminals, the TERM
environment variable is set by the program that chains to login
, and is inherited all of the way along to the interactive shell that executes once one has logged on. Where, precisely, this happens varies from system to system, and according to the kind of terminal.
Real, serial, terminals can vary in type, according to what's at the other end of the wire. So conventionally the getty
program is invoked with an argument that specifies the terminal type, or is passed the TERM
program from a service manager's service configuration data.
- On System 5
init
systems, one can see this in/etc/inittab
entries, which will read something along the lines ofS0:3:respawn:/sbin/agetty ttyS0 9600 vt100-nav
The last argument toagetty
in that line,vt100-nav
, is the terminal type set for/dev/ttyS0
. So/etc/inittab
is where to change the terminal type for real terminals on such systems. - On systemd systems, one can see this in the
/usr/lib/systemd/system/serial-getty@.service
unit file (/lib/systemd/system/serial-getty@.service
on un-merged systems), which readsEnvironment=TERM=vt100
setting theTERM
variable in the environment passed toagetty
. This service unit file is where to change the terminal type for real terminals on such systems. Note that it applies to all real terminals that employ this service unit template. (To change it for only individual terminals, one has to manually instantiate the template.) - On the BSDs,
init
takes the terminal type from the third field of each terminal's entry in the/etc/ttys
database, and setsTERM
from that in the environment that it executesgetty
with. So/etc/ttys
is where one changes the terminal type for real terminals on the BSDs.
Kernel virtual terminals, as you have noted, have a fixed type. Unlike NetBSD, which can vary the kernel virtual terminal type on the fly, Linux and the other BSDs have a single fixed terminal type implemented in the kernel's built-in terminal emulation program. On Linux, that type matches linux
from the terminfo database. (FreeBSD's kernel terminal emulation is a limited xterm
subset since version 9.)
- On systems using
mingetty
orvc-get-tty
(from the nosh package) the program "knows" that it can only be talking to a virtual terminal, and they hardwire the "known" virtual terminal types appropriate to the operating system that the program was compiled for. - On systemd systems, one can see this in the
/usr/lib/systemd/system/getty@.service
unit file (/lib/systemd/system/getty@.service
on un-merged systems), which readsEnvironment=TERM=linux
setting theTERM
variable in the environment passed toagetty
.
For kernel virtual terminals, one does not change the terminal type. The terminal emulator program in the kernel doesn't change, after all. It is incorrect to change the type. In particular, this will screw up cursor/editing key CSI sequence recognition. The linux
CSI sequences sent by the Linux kernel terminal emulator are different to the xterm
or vt100
CSI sequences sent by GUI terminal emulator programs in DEC VT mode.
Your GUI terminal emulator is one of many programs, from the SSH dæmon to screen
, that uses pseudo-terminals. What the terminal type is depends from what terminal emulator program is running on the master side of the pseudo-terminal, and how it is configured. Most GUI terminal emulators will start the program on the slave side with a TERM
variable whose value matches their terminal emulation on the master side. Programs like the SSH server will attempt to "pass through" the terminal type that is on the client end of the connection. Usually there is some menu or configuration option to choose amongst terminal emulations.
The gripping hand
The right way to detect colour capability is not to hardwire a list of terminal types in your script. There are an awful lot of terminal types that support colour.
The right way is to look at what termcap/terminfo says about your terminal type.
colour=0 if tput Co > /dev/null 2>&1 then test "`tput Co`" -gt 2 && colour=1 elif tput colors > /dev/null 2>&1 then test "`tput colors`" -gt 2 && colour=1 fi