Many terminal applications and linux utilities have support for colored output, made possible by ANSI escape sequences. There are sequences for many different terminal controls like moving cursors, setting titles and styling content. For brevity we only cover the text styling related ones, refer to the ECMA-48 standard if you need more than colors and text formatting.
Understanding ANSI escape sequences
Since terminals have no direct API a program could call, they instead rely on specifically formatted output to change terminal appearance or behavior. These were initially standardized by ANSI X3.64 and begin with an the ASCII ESC character, followed by a sequence of characters that the terminal interprets as a command - hence the name "ANSI escape sequence". Although the current standards ECMA-48 / ISO/IEC 6429 have long superseded ANSI X3.64, "ANSI escape sequence" remains the commonly used name.
The ESC characters can be output by most programs either in hexadecimal form \x1b or octal notation as \033. Some languages like bash also support the syntax \e to produce it, but most do not.
Escape sequences are structured like this:
\033[1;30mThe [ following the ESC character selects the command family. For terminal styling you will need CSI (Control Sequence Introducer) group, which uses [. Following it is a list of one or more numeric codes delimited by semicolons ;. The last character is called the final byte, which selects the mode the operation should use. Text styling will always use SGR (Select Graphic Rendition), using the letter m.
The codes within an escape sequence are applied from left to right, and conflicting ones will override the previous one. An escape sequence applies rules like text formatting or color until it is reset, either by a complete reset (0) or a selective one (22-29).
Core ANSI styles
These are the official codes defined by the ECMA-48 standard. While most terminals claim compatibility with this standard, they often omit some codes or implement their behavior differently.
Text control:
1- High intensity text. Most terminals render this text bold, some as bright color instead2- Faint/dimmed text, unreliable support3- Italic. Often missing in old or simple terminals4- Underline5- Blink. Rarely supported6- Rapid blink. Rarely supported7- Reverse video. Reverses foreground and background color, useful to highlight/mark text8- Conceal text. Renders text as whitespace, largely useless today. Prefer disabling echo instead9- Strikethrough. Crossed out text, unreliable support across terminals0- Complete reset. Disables all previous styles22- Disable bold/faint23- Disable italic24- Disable underline25- Disable blink27- Disable reverse video28- Disable text concealment29- Disable strikethrough
Foreground colors:
30- Black foreground31- Red foreground32- Green foreground33- Yellow foreground34- Blue foreground35- Magenta foreground36- Cyan foreground37- White foreground
Background colors:
41- Red background42- Green background43- Yellow background44- Blue background45- Magenta background46- Cyan background47- White background
You can check what core colors look like visually in your terminal with
for code in {30..37} {40..47}; \
do printf "\033[${code}m%3s\033[0m\n" "$code"; doneDo not rely on these colors too heavily, as they may not behave the same across terminals. Most terminals allow users to set their own theme with custom color codes, so nothing stops them from turning text yellow when the "green" escape sequence is used.
Even without user customizations, color shades visually differ between terminal implementations.
Bright colors
Technically an extension to the ECMA-48 standard, the bright colors are well-supported across most terminals and provide better visual clarity for terminal output:
Bright foreground colors:
90- Bright black foreground (often gray)91- Bright red foreground (often orange)92- Bright green foreground93- Bright yellow foreground94- Bright blue foreground95- Bright magenta foreground96- Bright cyan foreground97- Bright white foreground
Bright background colors:
100- Bright black background101- Bright red background102- Bright green background103- Bright yellow background104- Bright blue background105- Bright magenta background106- Bright cyan background107- Bright white background
You can check what bright colors look like visually in your terminal with
You can check what bright colors look like visually in your terminal with
for code in {90..97} {100..107}; \
do printf "\033[${code}m%3s\033[0m\n" "$code"; doneRemember that the "bold/high intensity" escape sequence may also render text as bright colors instead, which may lead to confusion.
As with the original 8 colors, the terminal theme may be altered to redefine what color is printed when selecting any escape sequence, so do not rely too heavily on these escape sequences to produce a specific color. Exact color shades also vary between terminal implementations.
xTerm extension
The xterm extensions brought more color support, first through 256 addon colors, then later full true color support from 24-bit RGB values. For modern terminals, you should always prefer RGB since terminals implementing one will almost certainly support both anyway, and RGB yields more control.
Note that the xterm extension is supported by most modern terminals, but simpler implementations like /dev/tty or virtual login terminals often don't implement them.
24bit RGB colors
38;2;R;G;Bmsets foreground color to RGB color. ReplaceR,GandBwith real 24bit RGB values48;2;R;G;Bmsets background color to RGB color. ReplaceR,GandBwith real 24bit RGB values
Unlike the 8/16 core colors, true color RGB values are not affected by terminal themes and do not vary visually between terminal implementations. While this may sound desirable, they are somewhat frowned upon as they may not work well with custom terminal themes, and users that spent time customizing their terminal appearance tend to get fairly upset when a program doesn't respect their choices.
Also note that accessibility is fully in your hands when using true color shades, since terminal high contrast or better readability settings will be ignored as well.
The xterm extension also contains other styling options to create clickable hyperlinks and set the terminal title, but we omit them here since they are less commonly used.
Robust terminal styling guidelines
There are some simple rules you can follow to avoid common issues with styled terminal output.
Make styling optional. Escape sequences only work inside terminals, so something as simple as a pipe | or redirecting output to a file will turn the output into a mess of real output and raw escape sequences. Most linux tools turn colors off by default and allow users to turn them on with the --color=on/auto flag if they want. If you want to have color by default, at least respect the NO_COLOR environment variable.
Always check if stdout is a terminal. Most users will want colored output on the terminal, but no escape sequences for other output targets. Providing an "auto" which uses language builtins like C's isatty to check if stdout is a terminal and enabling colors if true is what most users expect today. Do not rely on environment variables like TERM alone as they may be incorrect.
Prefer the core 8/16 colors. They respect custom theme colors, which may be vital for users that rely on accessibility themes for high contrast or visual impairments. RGB true color seems like a nice standardized option to get just the color you wanted, but it is rarely the better choice in the real world.
Do not encode meaning in color alone. You might be tempted to distinguish warnings from errors by using different colors, but this breaks when output is redirected to a log file or is piped into a viewer like less. Always ensure that the output text contains all the necessary information and context, and use color as a helper to quickly scan or segment output in environments that support it.
Do not rely on specific colors. As terminal themes can alter non-RGB color values, do not rely on the color alone in documentation or guides. If you refer to "the green portion of the output", at least provide a screenshot so users with different color schemes can see what you are talking about.