Bash tips: Colors and formatting (ANSI/VT100 Control sequences)

The ANSI/VT100 terminals and terminal emulators are not just able to display black and white text ; they can display colors and formatted texts thanks to escape sequences. Those sequences are composed of the Escape character (often represented by ”^[” or ”<Esc>”) followed by some other characters: ”<Esc>[FormatCodem”.

In Bash, the <Esc> character can be obtained with the following syntaxes:

  • \e
  • \033
  • \x1B

Examples:

Code (Bash) Preview
echo -e "\e[31mHello World\e[0m"
Hello World
echo -e "\033[31mHello\e[0m World"
Hello World

NOTE¹: The -e option of the echo command enable the parsing of the escape sequences.

NOTE²: The ”\e[0m” sequence removes all attributes (formatting and colors). It can be a good idea to add it at the end of each colored text. ;)

NOTE³: The examples in this page are in Bash but the ANSI/VT100 escape sequences can be used in every programming languages.

Formatting

Here are the most commonly supported control sequences for formatting text. Their support depends on the used terminal (see the compatibility list).

Set

Code Description Example Preview
1 Bold/Bright
echo -e "Normal \e[1mBold"
Normal Bold
2 Dim
echo -e "Normal \e[2mDim"
Normal Dim
4 Underlined
echo -e "Normal \e[4mUnderlined"
Normal Underlined
5 Blink 1)
echo -e "Normal \e[5mBlink"
Normal Blink
7 Reverse (invert the foreground and background colors)
echo -e "Normal \e[7minverted"
Normal inverted
8 Hidden (usefull for passwords)
echo -e "Normal \e[8mHidden"
Normal Hidden

Reset

Code Description Example Preview
0 Reset all attributes
echo -e "\e[0mNormal Text"
Normal Text
21 Reset bold/bright
echo -e "Normal \e[1mBold \e[21mNormal"
Normal Bold Normal
22 Reset dim
echo -e "Normal \e[2mDim \e[22mNormal"
Normal Dim Normal
24 Reset underlined
echo -e "Normal \e[4mUnderlined \e[24mNormal"
Normal Underlined Normal
25 Reset blink
echo -e "Normal \e[5mBlink \e[25mNormal"
Normal Blink Normal
27 Reset reverse
echo -e "Normal \e[7minverted \e[27mNormal"
Normal inverted Normal
28 Reset hidden
echo -e "Normal \e[8mHidden \e[28mNormal"
Normal Hidden Normal

8/16 Colors

The following colors works with most terminals and terminals emulators 2), see the compatibility list for more informations.

NOTE: The colors can vary depending of the terminal configuration.

Foreground (text)

Code Color Example Preview
39 Default foreground color
echo -e "Default \e[39mDefault"
Default Default
30 Black
echo -e "Default \e[30mBlack"
Default Black
31 Red
echo -e "Default \e[31mRed"
Default Red
32 Green
echo -e "Default \e[32mGreen"
Default Green
33 Yellow
echo -e "Default \e[33mYellow"
Default Yellow
34 Blue
echo -e "Default \e[34mBlue"
Default Blue
35 Magenta
echo -e "Default \e[35mMagenta"
Default Magenta
36 Cyan
echo -e "Default \e[36mCyan"
Default Cyan
37 Light gray
echo -e "Default \e[37mLight gray"
Default Light gray
90 Dark gray
echo -e "Default \e[90mDark gray"
Default Dark gray
91 Light red
echo -e "Default \e[91mLight red"
Default Light red
92 Light green
echo -e "Default \e[92mLight green"
Default Light green
93 Light yellow
echo -e "Default \e[93mLight yellow"
Default Light yellow
94 Light blue
echo -e "Default \e[94mLight blue"
Default Light blue
95 Light magenta
echo -e "Default \e[95mLight magenta"
Default Light magenta
96 Light cyan
echo -e "Default \e[96mLight cyan"
Default Light cyan
97 White
echo -e "Default \e[97mWhite"
Default White

Background

Code Color Example Preview
49 Default background color
echo -e "Default \e[49mDefault"
Default Default
40 Black
echo -e "Default \e[40mBlack"
Default Black
41 Red
echo -e "Default \e[41mRed"
Default Red
42 Green
echo -e "Default \e[42mGreen"
Default Green
43 Yellow
echo -e "Default \e[43mYellow"
Default Yellow
44 Blue
echo -e "Default \e[44mBlue"
Default Blue
45 Magenta
echo -e "Default \e[45mMagenta"
Default Magenta
46 Cyan
echo -e "Default \e[46mCyan"
Default Cyan
47 Light gray
echo -e "Default \e[47mLight gray"
Default Light gray
100 Dark gray
echo -e "Default \e[100mDark gray"
Default Dark gray
101 Light red
echo -e "Default \e[101mLight red"
Default Light red
102 Light green
echo -e "Default \e[102mLight green"
Default Light green
103 Light yellow
echo -e "Default \e[103mLight yellow"
Default Light yellow
104 Light blue
echo -e "Default \e[104mLight blue"
Default Light blue
105 Light magenta
echo -e "Default \e[105mLight magenta"
Default Light magenta
106 Light cyan
echo -e "Default \e[106mLight cyan"
Default Light cyan
107 White
echo -e "Default \e[107mWhite"
Default White

88/256 Colors

Some terminals (see the compatibility list) can support 88 or 256 colors. Here are the control sequences that permit you to use them.

NOTE¹: The colors number 256 is only supported by vte (GNOME Terminal, XFCE4 Terminal, Nautilus Terminal, Terminator,…).

NOTE²: The 88-colors terminals (like rxvt) does not have the same color map that the 256-colors terminals. For showing the 88-colors terminals color map, run the ”256-colors.sh” script in a 88-colors terminal.

Foreground (text)

For using one of the 256 colors on the foreground (text color), the control sequence is ”<Esc>[38;5;ColorNumberm” where ColorNumber is one of the following colors:

XTerm 256 color list (foreground)

Examples:

Code (Bash) Preview
echo -e "\e[38;5;82mHello \e[38;5;198mWorld"
Hello World
for i in {16..21} {21..16} ; do echo -en "\e[38;5;${i}m#\e[0m" ; done ; echo
Blue gradiant

Background

For using one of the 256 colors on the background, the control sequence is ”<Esc>[48;5;ColorNumberm” where ColorNumber is one of the following colors:

XTerm 256 color list (background)

Examples:

Code (Bash) Preview
echo -e "\e[40;38;5;82m Hello \e[30;48;5;82m World \e[0m"
Hello World
for i in {16..21} {21..16} ; do echo -en "\e[48;5;${i}m \e[0m" ; done ; echo
Blue gradiant

Attributes combination

Terminals allow attribute combinations. The attributes must be separated by a semicolon (”;”).

Examples:

Description Code (Bash) Preview
Bold + Underlined
echo -e "\e[1;4mBold and Underlined"
Bold and Underlined
Bold + Red forground + Green background
echo -e "\e[1;31;42m Yes it is awful \e[0m"
Yes it is awful

Terminals compatibility

Terminal Formatting Colors Comment
Bold Dim Underlined Blink invert Hidden 8 16 88 256
aTerm ok - ok - ok - ok ~ - - Lighter background instead of blink.
Eterm ~ - ok - ok - ok ~ - ok Lighter color instead of Bold. Lighter background instead of blink. Can overline a text with the ”^[[6m” sequence.
GNOME Terminal ok ok ok - ok ok ok ok - ok Strikeout with the ”^[[9m” sequence.
Guake ok ok ok - ok ok ok ok - ok Strikeout with the ”^[[9m” sequence.
Konsole ok - ok ok ok - ok ok - ok
Nautilus Terminal ok ok ok - ok ok ok ok - ok Strikeout with the ”^[[9m” sequence.
rxvt ok - ok ~ ok - ok ok ok - If the background is not set to the default color, Blink make it lighter instead of blinking. Support of italic text with the ”^[[3m” sequence.
Terminator ok ok ok - ok ok ok ok - ok Strikeout with the ”^[[9m” sequence.
Tilda ok - ok - ok - ok ok - - Underline instead of Dim. Convert 256-colors in 16-colors.
XFCE4 Terminal ok ok ok - ok ok ok ok - ok Strikeout with the ”^[[9m” sequence.
XTerm ok - ok ok ok ok ok ok - ok
xvt ok - ok - ok - - - - -
Linux TTY ok - - - ok - ok ~ - - Specials colors instead of Dim and Underlined. Lighter background instead of Blink, Bug with 88/256 colors.
VTE Terminal 3) ok ok ok - ok ok ok ok - ok Strikeout with the ”^[[9m” sequence.

Notations used in the table:

  • ok”: Supported by the terminal.
  • ~”: Supported in a special way by the terminal.
  • -”: Not supported at all by the terminal.

Demonstration programs

Colors and formatting (16 colors)

Screenshot of the color_and_formatting.sh script

The following shell script displays a lot of possible combination of the attributes (but not all, because it uses only one formatting attribute at a time).

colors_and_formatting.sh
#!/bin/bash
 
# This program is free software. It comes without any warranty, to
# the extent permitted by applicable law. You can redistribute it
# and/or modify it under the terms of the Do What The Fuck You Want
# To Public License, Version 2, as published by Sam Hocevar. See
# http://sam.zoy.org/wtfpl/COPYING for more details.
 
#Background
for clbg in {40..47} {100..107} 49 ; do
	#Foreground
	for clfg in {30..37} {90..97} 39 ; do
		#Formatting
		for attr in 0 1 2 4 5 7 ; do
			#Print the result
			echo -en "\e[${attr};${clbg};${clfg}m ^[${attr};${clbg};${clfg}m \e[0m"
		done
		echo #Newline
	done
done
 
exit 0

256 colors

Screenshot of the 256-colors.sh script

The following script display the 256 colors available on some terminals and terminals emulators like XTerm and GNOME Terminal.

256-colors.sh
#!/bin/bash
 
# This program is free software. It comes without any warranty, to
# the extent permitted by applicable law. You can redistribute it
# and/or modify it under the terms of the Do What The Fuck You Want
# To Public License, Version 2, as published by Sam Hocevar. See
# http://sam.zoy.org/wtfpl/COPYING for more details.
 
for fgbg in 38 48 ; do #Foreground/Background
	for color in {0..256} ; do #Colors
		#Display the color
		echo -en "\e[${fgbg};5;${color}m ${color}\t\e[0m"
		#Display 10 colors per lines
		if [ $((($color + 1) % 10)) == 0 ] ; then
			echo #New line
		fi
	done
	echo #New line
done
 
exit 0

Links

1) Does not work with most of the terminal emulators, works in the tty and XTerm.
2) Some terminals supports only the first 8 colors (30..37 and 40..47), and some others does not support any color at all.
3) GTK Widget used in GNOME Terminal, Nautilus Terminal, XFCE4 Terminal…

Discussion

William C GrisaitisWilliam C Grisaitis, 2011/11/13 02:00
Thanks! This was invaluable in customizing my PS1's:

if [[ ${EUID} == 0 ]] ; then
PS1='\e[1;31;48;5;234m\u \e[38;5;240mon \e[1;38;5;28;48;5;234m\h \e[38;5;54m\d \@\e[0m\n\e[0;31;48;5;234m[\w] \e[1m\$\e[0m '
else
PS1='\e[1;38;5;56;48;5;234m\u \e[38;5;240mon \e[1;38;5;28;48;5;234m\h \e[38;5;54m\d \@\e[0m\n\e[0;38;5;56;48;5;234m[\w] \e[1m\$\e[0m '
fi

@caravaggisto
Barry ScottBarry Scott, 2012/06/14 21:41
Great work on terminal compatibility.I have been trying to get blinking text on a Linux tty(at the console). Do you have any idea if it's possible?
Fabien LOISONFabien LOISON, 2012/06/14 21:54
I Think it is possible, but I haven't found how to do that
Barry ScottBarry Scott, 2012/06/14 22:11
I have looked at infocmp for linux the terminal(TERM=linux) I use and I see blink referenced in it but I'm having a hard time understanding the file format. The cursor blinks why disable blinking text.
WarronWarron, 2013/04/04 19:09
Great page on bash coloring and attributes.

I was actually looking to find out if there is a way to combine attributes {BOLD, Blink, etc} around the same subset of text in doing a bash echo command with the -e option.

Can you help with this matter?


\\War
Fabien LOISONFabien LOISON, 2013/04/04 21:54
Hello,

You can combine attributes with a semicolon:

echo -e "\e[1;5m Bold+Blink \e[0m"
echo -e "\e[1;4;31m Bold+Underline+Red \e[0m"

Note that the blink attribute is supported only by few terminals (XTerm, tty).

Regards,
WarronWarron, 2013/04/11 21:49
Thank you Fabian.

That worked splendidly! You are the man!
PauloPaulo, 2013/07/23 17:21
I want to use 256 color scheme. How can I set a 256-color prompt to only show in terminals that support it?
Fabien LOISONFabien LOISON, 2013/07/23 20:21
Hello,

You can use the "tput colors" command to know how many colors are supported by the terminal (it is based on the terminfo database):

if [ $(tput colors) -ge 256 ] ; then
PS1="your 256 color prompt"
else
PS1="your default prompt"
fi
RindealRindeal, 2013/10/18 00:55
I think, printf is better to use to show that 256-color palette, like this:

for fgbg in 38 48 ; do #Foreground/Background
for color in {0..256} ; do #Colors
#Display the color
printf "\e[${fgbg};5;%sm %3s \e[0m" "${color}" "${color}"
#Display 10 colors per lines
if [ $((($color + 1) % 10)) == 0 ] ; then
echo #New line
fi
done
echo #New line
done
Fabien LOISONFabien LOISON, 2013/10/19 11:22
Yes it works with printf too :)
Luke LeeLuke Lee, 2013/12/05 02:21
Splendid!
ling talfiling talfi, 2014/01/15 11:08
Best recap ever found !
tstrtstr, 2014/02/19 00:42
Nice tips! Tho it would be better to arrange the color tables like this:

testColFunc(){
str="$(printf "% 4d" "$1")"
echo -ne "$str \e[48;5;${1}m$str \e[0m"
}
for line in {0..35}
do
if [[ line -le 15 ]]
then testColFunc "$line"
else echo -n " "
fi
for col in {0..5}
do
code="`expr "$col" \* 36 + "$line" + 16`"
testColFunc "$code"
done
if [[ line -le 23 ]]
then testColFunc "`expr 232 + "$line"`"
fi
echo
done

Replace 48 with 38 for fg colors
This makes it clear how to get any color, and the fact that you can control the R, G & B color channels separately (6 values per channel):
16 + 36*(round R*5) + 6*(round G*5) + (round B*5)
(In case this is needed: You can use the above code for any purpose)
tstrtstr, 2014/02/19 14:05
Also dim and bold seem to overrule eachother, and resetting either resets both (GNOME Terminal on Ubuntu).
LutzLutz, 2014/07/31 10:30
thanks for that hint. I'm using Konsole and it does not support dim. It also does not support resetting bold by using \033[21m but resetting bold works with the code for resetting dim \033[22m
vzvz, 2014/04/26 03:22
Here's a nice one: "\e[H\e[J" clears the screen.
a-rona-ron, 2014/06/17 06:23
This is working for me for now (it's only lightly tested, fails gracefully if the numbers are too high, fails ungracefully if you give too few arguments, and uses features in bash new to me (hey, been away for awhile), so not sure if they are standard or new... with that out of the way:

function c_clr() { echo -en "\e[0m" ; }
function c_ansi() { [ $1 -lt 16 ] && echo -en "\e[38;5;$1m" || c_clr ; }
function c_grey() { [ $1 -lt 24 ] && echo -en "\e[38;5;$(($1+232))m" || c_clr ; }
function c_rgb() { [ $1 -lt 6 -a $2 -lt 6 -a $3 -lt 6 ] && echo -en "\e[38;5;$((16+(36*$1)+(6*$2)+$3))m" || c_clr ; }
function cb_ansi() { [ $1 -lt 16 ] && echo -en "\e[48;5;$1m" || c_clr ; }
function cb_grey() { [ $1 -lt 24 ] && echo -en "\e[48;5;$(($1+232))m" || c_clr ; }
function cb_rgb() { [ $1 -lt 6 -a $2 -lt 6 -a $3 -lt 6 ] && echo -en "\e[48;5;$((16+(36*$1)+(6*$2)+$3))m" || c_clr ; }

Now I can do things like echo "$(c_grey 15)I'm light Grey$(c_clr)" and
echo "$(cb_rgb 5 0 0)Red$(cb_rgb 0 5 0)Green$(cb_rgb 0 0 5)Blue$(c_clr)"

At any rate, hope this helps someone.
a-rona-ron, 2014/06/17 06:24
Ah crap... had to change ampersands to %26 for the preview... guess not for the save... at any rate, %26%26 should be && (two ampersands crammed together in case this fails too...)
Fabien LOISONFabien LOISON, 2014/06/17 10:47
I fixed the %26 :)
Amiga 4everAmiga 4ever, 2014/07/25 01:36
My small contribution: http://pastebin.com/L4fNvpYc
It was easier to code than to calculate limits and steps
Dan PrittsDan Pritts, 2014/09/22 21:40
Tested with iTerm2 (https://code.google.com/p/iterm2/) build 20140629 with 12 point "Menlo" font.



Note, MacOS 10.9 ships with bash 3.2.51, which does not appear to support \e as escape in the echo builtin. Had to change test scripts to use a verbatim escape.



256 colors work.



bold, blink, and underline work. Dim and hidden don't.



reverse works, except that tabs aren't reverse-video'd, they are just default background color.



Not sure what esc[9m is supposed to do but i guess i struck out.



Supports a few interesting escape codes to interact with MacOS. https://code.google.com/p/iterm2/wiki/ProprietaryEscapeCodes
Dan PrittsDan Pritts, 2014/09/22 21:51
Just noticed that iTerm2 2.0 is out, re-tested with similar results. Also, \e[21m to unset bold doesn't work but the other unset's do.
Enter your comment:
AEAKV
 
 
bash/tip_colors_and_formatting.txt · Last modified: 2013/05/09 17:09 (external edit)