When I open a terminal window with the GNOME Terminal emulator in the desktop GUI the shell TERM environment variable defaults to the value xterm
.
If I use CTL+ALT+F1 to switch to a console TTY window and echo $TERM
the value is set to linux
.
My motivation for asking is that inside my ~/.bashrc
file a variable is used to determine if a color shell is provided or just good old fashioned monochrome.
# set a fancy prompt (non-color, unless we know we "want" color)
case "$TERM" in
xterm-color) color_prompt=yes;;
esac
In both the console shell and the Gnome Terminal emulator shell if I type
export TERM=xterm-color
source /.bashrc
both shells change to color mode (something I'd like to have happen always in both).
Where do the default TERM
values get set please and where is the best place to change their defaults, if at all possible? There appears to be nothing in the terminal emulator GUI to select or set the default TERM value.
I did consider just adding the line export TERM=xterm-color
to the top of my ~/.bashrc
file but my gut instinct tells this is not the best solution and my Google searches haven't yet led me to a good answer.
I'm running Ubuntu 15.04 Desktop Edition (Debian Based).
Best Answer
In lots of places, depending
On virtual terminals and real terminals, the
TERM
environment variable is set by the program that chains tologin
, 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 terminals
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 theTERM
program from a service manager's service configuration data.init
systems, one can see this in/etc/inittab
entries, which will read something along the lines of 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./usr/lib/systemd/system/serial-getty@.service
unit file (/lib/systemd/system/serial-getty@.service
on un-merged systems), which used to read setting theTERM
variable in the environment passed toagetty
.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.systemd's variability
The
serial-getty@.service
service unit file, or drop-in files that apply thereto, is where to change the terminal type for real terminals on systemd systems. Note that such a change applies to all terminal login services that employ this service unit template. (To change it for only individual terminals, one has to manually instantiate the template, or add drop-ins that only apply to instantiations.)systemd has had at least four mechanisms during its lifetime for picking up the value of the
TERM
environment variable. At the time of first writing this answer, as can be seen, there was anEnvironment=TERM=something
line in the template service unit files. At other times, the typeslinux
andvt102
were hard-wired into thegetty
andserial-getty
service unit files respectively. More recently, the environment variable has been inherited from process #1, which has set it in various ways.As of 2020, the way that systemd decides what terminal type to specify in a service's
TERM
environment variable is quite complex, and not documented at all. The way to change it remains a drop-in configuration file withEnvironment=TERM=something
. But where the default value originates from is quite variable. Subject to some fairly complex to explain rules that involve theTTYPath=
settings of individual service units, it can be one of three values: a hardwiredlinux
, a hardwiredvt220
(no longervt102
), or the value of theTERM
environment variable that process #1 inherited, usually from the kernel/bootstrap loader.(Ironically, the
getttyent()
mechanism still exists in the GNU C library, and systemd could have re-used the/etc/ttys
mechanism.)kernel virtual terminals
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 since version 9 has beenteken
. Prior to version 9 it wascons25
OpenBSD's ispccon
.)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./usr/lib/systemd/system/getty@.service
unit file (/lib/systemd/system/getty@.service
on un-merged systems), which read 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 thexterm
orvt100
CSI sequences sent by GUI terminal emulator programs in DEC VT mode. (In fact, they are highly idiosyncratic and non-standard, and different both to all real terminals that I know of, and to pretty much all other software terminal emulators apart from the one built into Linux.)GUI terminal emulators
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 aTERM
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.
Further reading
TERM
. nosh Guide. Softwares.