Understanding color codes in the terminal
Everyone loves colors in the terminal, but how do they work?
The way colors are set is by sending a control character called escape
(not to be confused with an escape character.)
In ASCII esc
is a specific character with the value 0x1b
, often being written in caret notation as ^[
.
In technical documents ^[
is often denoted as CSI
, or Control Sequence Introducer
.
In order to modify graphics, we send the SGR
sequence (short for Select Graphic Rendition
.)
The SGR
sequence is structured like this;
CSI [ <parameters> m
The parameters that we'll be focusing on are as follows;
0 default rendition; cancels the effects of any previous SGR occurence
3[0-7] sets the foreground color
4[0-7] sets the background color
38 extended set foreground color
48 extended set background color
Originally the specification only supported 8 colors, though some implemented a "bright" mode by complementing bold mode (SGR 1
) to the default colors.
Intensity | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|---|---|
Normal | Black | Red | Green | Yellow | Blue | Magenta | Cyan | White |
Bright | Black | Red | Green | Yellow | Blue | Magenta | Cyan | White |
As color technology advanced, it was decided to add 256-color support to terminals.
For this, they used the SGR 38
as it was reserved for future use.
The reserved extended set allowed two argument forms, and both forms are implemented in many terminal emulators today.
^[ [ 38;5;<N> m
^[ [ 38;2;<R>;<G>;<B> m
The former setting the color to N
, where N
is one of the predefined 256 colors.
The latter takes a RGB values.
If we look at calmar.ws's 256 index, we can pick any color, like for example 154
, and print it out using printf
.
printf 'here is text with \033[38;5;154m color \033[0m and without\n'
Or to print a table of all the 256 colors
jot 255 | while read
do
printf '\033[48;5;%dm \033[0m ' $REPLY
done
echo # flush
If you don't have jot
installed, replace it with seq
.