67

I have tested this with both Ubuntu 12.04 and Debian 7. When I do

echo $TERM

I get

xterm

But if I use the dropdown menu "help" > "about" then it says gnome terminal 3.4.1.1.

Does this mean I am using just gnome-terminal? Or just xterm? Or is gnome-terminal an extension of xterm? I'm confused.

mulllhausen
  • 2,668

4 Answers4

63

What is $TERM for?

The $TERM variable is for use by applications to take advantage of capabilities of that terminal.

For example, if a program wants to display colored text, it must first find out if the terminal you're using supports colored text, and then if it does, how to do colored text.

The way this works is that the system keeps a library of known terminals and their capabilities. On most systems this is in /usr/share/terminfo (there's also termcap, but it's legacy not used much any more).

So let's say you have a program that wants to display red text. It basically makes a call to the terminfo library that says "give me the sequence of bytes I have to send for red text for the xterm terminal". Then it just takes those bytes and prints them out.
You can try this yourself by doing tput setf 4; echo hi. This will get the setf terminfo capability and pass it a parameter of 4, which is the color you want.


Why gnome terminal lies about itself:

Now let's say you have some shiny new terminal emulator that was just released, and the system's terminfo library doesn't have a definition for it yet. When your application goes to look up how to do something, it will fail because the terminal isn't known.

The way your terminal gets around this is by lying about who it is. So your gnome terminal is saying "I'm xterm".

Xterm is a very basic terminal that has been around since the dawn of X11, and thus most terminal emulators support what it supports. So by gnome terminal saying it's an xterm, it's more likely to have a definition in the terminfo library.

The downside to lying about your terminal type is that the terminal might actually support a lot more than xterm does (for example, many new terminals support 256 colors, while older terminals only supported 16). So you have a tradeoff, get more features, or have more compatibility. Most terminals will opt for more compatibility, and thus choose to advertise themselves as xterm.

If you want to override this, many terminals will offer some way of configuring the behavior. But you can also just do export TERM=gnome-terminal.

phemmer
  • 71,831
35

The TERM environment variable indicates the terminal type, not the terminal application. TERM has a specific purpose: it tells applications running in that terminal how to interact with the terminal.

Applications interact with terminals by writing escape sequences — sequences of characters that include nonprintable characters and have effects such as moving the cursor, erasing part of the screen, changing the current color, etc. In the old days, different brands of physical terminals had different sets of escape sequences. Therefore the operating system maintains a database of terminal types and their characteristics. The traditional database is termcap (“TERMinal CAPabilities”); many modern systems and applications have switched to terminfo. Both databases are indexed by the name of the terminal type, and applications query them using the terminal type name from the TERM environment variables.

Nowadays, most terminals use a standard set of escape sequences with a few common sets of extensions, so you won't see many different values of TERM. Most GUI terminal emulators are compatible with xterm, the traditional X terminal (which is still used and maintained).

Terminal emulators that differ from xterm may add their own entry to the terminal database under their own name. However this doesn't mesh well with remote shells. A program running on machine A but which is displaying on machine B, for example because it was launched through ssh from B to A, needs to query the terminal database on machine A. Remote login methods such as ssh carry over the TERM environment variable, but this is helpful only when B's terminal database also has an entry for the value user on A. Therefore many terminal emulators stick to TERM=xterm which is pretty much universally known.

The differentiation between terminals by and large does not come from the way applications interact with them, but by the way the terminals interact with the user and fit in their environment. For example, Gnome Terminal looks good on Gnome and provides tabs and other niceties; Konsole looks good on KDE and provides tabs and other niceties; urxvt has a small memory requirement; Console2 runs on Windows; screen and tmux provide sessions that can be attached to different parent terminals; and so on. Since none of these features make a difference to applications running in the terminal, most terminal emulators use TERM=xterm.

To find out what terminal a shell is running in (assuming the shell is running directly in a terminal), look at the parent of the shell:

ps -p$PPID
  • 1
    Running ps -p$PPID doesn't seem to tell me what terminal I'm running. Or at least not in a way I understand. Do you have an example output/response? – user3731622 Mar 21 '18 at 17:17
  • @user The output is a bunch of numbers and cryptic abbreviations followed by a command line. Under most circumstances, the command line is the one that started the terminal emulator in which the shell is running. – Gilles 'SO- stop being evil' Mar 21 '18 at 20:14
  • The output on a Synology system isn't helpful: ps -p$PPID 812 ? 00:00:00 sshd – Artem Russakovskii Aug 29 '22 at 16:43
  • @ArtemRussakovskii That tells you that the shell is running in a terminal provided by sshd. Since sshd just relays data between the application and the “real” terminal, that doesn't tell you anything about the terminal type. There's no fully reliable way to do that, it's like finding out the terminal that screen or tmux is attached to. – Gilles 'SO- stop being evil' Aug 29 '22 at 17:26
12

The environment variable TERM does not mean the terminal you are using.

Quoting gnu.org:

The environment variable TERM contains a identifier for the text window's capabilities. You can get a detailed list of these cababilities by using the > ‘infocmp’ command, using ‘man 5 terminfo’ as a reference.

When producing text with embedded color directives, msgcat looks at the TERM variable. Text windows today typically support at least 8 colors. Often, however, the text window supports 16 or more colors, even though the TERM variable is set to a identifier denoting only 8 supported colors. It can be worth setting the TERM variable to a different value in these cases:

xterm is in most cases built with support for 16 colors. It can also be built with support for 88 or 256 colors (but not both). You can try to set TERM to either xterm-16color, xterm-88color, or xterm-256color. rxvt

rxvt is often built with support for 16 colors. You can try to set TERM to rxvt-16color. konsole

konsole too is often built with support for 16 colors. You can try to set TERM to konsole-16color or xterm-16color.

After setting TERM, you can verify it by invoking ‘msgcat --color=test’ and seeing whether the output looks like a reasonable color map. The environment variable TERM contains a identifier for the text window's capabilities. You can get a detailed list of these cababilities by using the ‘infocmp’ command, using ‘man 5 terminfo’ as a reference.

mavillan
  • 3,097
1

I think it's worth noting that you can find out the answer to your initial question by running ps -p $$, i.e. learn what is the process with the current pid. Sample output is:

    PID TTY          TIME CMD
3045221 pts/17   00:00:00 bash

which is quite clear about what terminal it is.

YakovL
  • 127
  • +1 Most people that Google this are looking for this answer and not a 12 paragraph essay about $TERM – Kellen Stuart Apr 19 '22 at 17:17
  • This doesn't make 'clear' the terminal -- a pty-slave (pts) can be connected to any terminal or no terminal at all, and it doesn't even try to identify the terminal type which is what the Q asked for. @KellenStuart: if you want short wrong answers, don't bother searching, just use '' (the empty string) as the answer to every question. – dave_thompson_085 Apr 20 '22 at 02:28
  • @dave_thompson_085 could you clarify what scenario you are referring to? Are you saying that in some cases we'll see "pts" or "pty-slave" in the CMD column; how to reproduce it? – YakovL Apr 20 '22 at 07:49
  • I see what @dave_thompson_085 is saying. The title explicitly says "terminal type". I read it as just "which terminal am I using". – Kellen Stuart Apr 20 '22 at 16:41
  • 2
    This answer is wrong, it tells you what shell you are using, not what terminal. Getting the terminal is much harder: ps -p $$ = 787175 pts/36 00:00:00 bash. Bash is not a terminal. Getting a reasonably reliable report on true terminal running the command is very difficult, and can't be done in a one, or 10, liner. The OP was about terminal, not shell. You can get what is often right however with a few more steps, but it won't always be right. The parent of the parent is usually the terminal, but not always. – Lizardx Aug 29 '22 at 18:43