1. Introduction
Colors are useful for design, but they can have a functional purpose as well. Because of this, knowing whether an environment supports their use can be both convenient and practical.
In this tutorial, we’ll look at ways to check the color support of a terminal, i.e., the command line interface (CLI). First, we discuss terminal colors in general. After that, we look at manual and automatic methods to find out whether our terminal can print in color.
We tested the code in this tutorial on Debian 11 (Bullseye) with GNU Bash 5.1.4. It should work in most POSIX-compliant environments.
2. Terminal Colors
The human eye can perceive around 10 million colors. Hence, a graphical processing unit (GPU) and a color monitor are usually standard parts of most home system setups.
Although servers are predominantly headless, most client systems that connect to them aren’t. Thus, we’re able to leverage colors in many end-user and administrative tasks.
For example, setting up a colored prompt can make it easier to navigate and keep track of paths:
$ echo $PS1
\[\e]0;\u@\h: \w\a\]${debian_chroot:+($debian_chroot)}\[\033[01;35m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$
On the other hand, we can write colors to files and output colored file content:
$ echo -e "\033[34mBLUE\033[00m in blue." > blue
$ cat blue
BLUE in blue.
Here, BLUE is colored blue.
There are many ways to output colors in the terminal. Yet, on a lower level, color output comes down to escape sequences like \033[34 above.
Removing the escape code \033 from \033[34, we’re left with the foreground color code command sequence [34 for blue. In fact, we can iterate through all 256 color values with a script:
for c in {0..255}; do
printf "\033[48;5;%sm%3d\033[0m " "$c" "$c"
if (( c == 15 )) || (( c > 15 )) && (( (c-15) % 6 == 0 )); then
printf "\n";
fi
done
For all $c values from 0 to 255, we use printf to print them with the respective color number.
Many commands automatically detect and output colors where and when appropriate. Let’s see how we can achieve this.
3. Terminal Color Capability
Whether it’s a TTY, PTY, or even a terminal emulator, there are different ways to see whether our current terminal supports colors.
3.1. Manual Checks
Naturally, a simple manual test with a script or command can let us know whether the current environment can display colors. For example, let’s see the output of our earlier attempt:
$ for c in {0..255}; do
printf "\033[48;5;%sm%3d\033[0m " "$c" "$c"
if (( c == 15 )) || (( c > 15 )) && (( (c-15) % 6 == 0 )); then
printf "\n";
fi
done
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
16 17 18 19 20 21
[...]
If the output of these color escape sequences consists of consecutive numbers over different-colored backgrounds, the terminal can print colors. Otherwise, there will be no colors, and sometimes we might even see the escape sequences themselves, depending on how rudimentary the environment is.
3.2. tput
Alternatively, we can check terminal color support with the tput command:
$ tput colors
256
Here, the colors subcommand of tput shows us the current terminal can output 256 different colors. Of course, it might also be less, e.g., 8 or even 2 (black and white).
Using tput, we can detect the color capabilities automatically. Further, the ability to print colors also means we can use tput and escape sequences for other functions as well.
Still, tput only gets the current capabilities based on the value of a special environment variable.
3.3. $TERM Variable
The $TERM shell environment variable sets the current terminal type:
$ echo $TERM
xterm-256color
In this case, we’re using the 256-color version of the xterm virtual terminal.
Since there are layers of terminals and hardware can often simulate many, we can sometimes change the value of $TERM based on our needs and the physical support.
Conveniently, as we saw above, some values hint at their color capability in the name.
4. Summary
In this article, we looked at terminal color support and ways to detect it.
In conclusion, while we can detect whether our terminal can output in color, depending on the method we choose, it might not provide a definitive answer.