Outputting text in a terminal can result in a monochrome experience for the user. Adding color is easy, so here, I provide a script that includes helper methods for outputting text, using defined colors, and handling contrast.
Introduction
The default text output to a terminal is monochromatic and doesn't provide a simple method to provide context. For instance, you may want an error to appear in red, success in green, or important info to be output in bold.
Adding color to your terminal output is straightforward and involves outputting the correct control characters before your text.
This is a companion article to How to change text color in a Linux terminal.
Terminal Colors
To output colored text, you need to echo
the control characters for the required color, then output your text, and then (to be tidy) reset the output back to defaults. The following table lists the codes:
Color | Foreground | Background |
Default | ESC[39m | ESC[49m |
Black | ESC[30m | ESC[40m |
Dark red | ESC[31m | ESC[41m |
Dark green | ESC[32m | ESC[42m |
Dark yellow (Orange-ish) | ESC[33m | ESC[43m |
Dark blue | ESC[34m | ESC[44m |
Dark magenta | ESC[35m | ESC[45m |
Dark cyan | ESC[36m | ESC[46m |
Light gray | ESC[37m | ESC[47m |
Dark gray | ESC[90m | ESC[100m |
Red | ESC[91m | ESC[101m |
Green | ESC[92m | ESC[101m |
Orange | ESC[93m | ESC[103m |
Blue | ESC[94m | ESC[104m |
Magenta | ESC[95m | ESC[105m |
Cyan | ESC[96m | ESC[106m |
White | ESC[97m | ESC[107m |
and the reset code is ESC[0m where ESC is the escape code.
The format of the string for foreground color is:
"ESC[" + "<0 or 1, meaning normal or bold>;" + "<color code> + "m"
and for background:
"ESC[" + "<color code>" + "m"
These codes can be output together in order to change fore- and back-ground colors simultaneously.
Using the Code
Before you can output the color code, you need to generate the ESC sequence. It's probably easiest to do that once and store it for later:
:: Sets up the ESC string for use later in this script
:setESC
for /F "tokens=1,2 delims=#" %%a in ('"prompt #$H#$E# & echo on & for %%b in (1) do rem"') do (
set ESC=%%b
exit /B 0
)
exit /B 0
This will set a variable ESC
with the correct sequence.
A simple example of outputting red text:
setlocal enabledelayedexpansion
call :setESC
echo !ESC
Handling Contrast
Suppose we have defined a set of predefined colors and we want to use them to ensure consistency:
set color_primary=Blue
set color_mute=Gray
set color_info=Yellow
set color_success=Green
set color_warn=DarkYellow
set color_error=Red
If we output text using these as background colors, we get:
call :WriteLine
call :WriteLine "Default color on predefined background"
call :WriteLine
call :WriteLine " Default colored background" "Default"
call :WriteLine " Primary colored background" "Default" %color_primary%
call :WriteLine " Mute colored background" "Default" %color_mute%
call :WriteLine " Info colored background" "Default" %color_info%
call :WriteLine " Success colored background" "Default" %color_success%
call :WriteLine " Warning colored background" "Default" %color_warn%
call :WriteLine " Error colored background" "Default" %color_error%

Things are a bit murky so let's add one more function that will provide a contrasting foreground on whatever background we choose.
:: Sets the name of a color that will providing a contrasting foreground
:setContrastForeground
set background=%~1
if "!background!"=="" background=Black
if /i "!background!"=="Black" set contrastForeground=White
if /i "!background!"=="DarkRed" set contrastForeground=White
if /i "!background!"=="DarkGreen" set contrastForeground=White
if /i "!background!"=="DarkYellow" set contrastForeground=White
if /i "!background!"=="DarkBlue" set contrastForeground=White
if /i "!background!"=="DarkMagenta" set contrastForeground=White
if /i "!background!"=="DarkCyan" set contrastForeground=White
if /i "!background!"=="Gray" set contrastForeground=Black
if /i "!background!"=="DarkGray" set contrastForeground=White
if /i "!background!"=="Red" set contrastForeground=White
if /i "!background!"=="Green" set contrastForeground=White
if /i "!background!"=="Yellow" set contrastForeground=Black
if /i "!background!"=="Blue" set contrastForeground=White
if /i "!background!"=="Magenta" set contrastForeground=White
if /i "!background!"=="Cyan" set contrastForeground=Black
if /i "!background!"=="White" set contrastForeground=Black
exit /B 0
We've already wired this up in the Write
methods: If the foreground color is set as "Contrast
", then the foreground will be set as something that has a decent contrast to the given background.
To use, we simply do:
call :WriteLine " Primary colored background" "Contrast" %color_primary%
call :WriteLine " Mute colored background" "Contrast" %color_mute%
call :WriteLine " Info colored background" "Contrast" %color_info%
call :WriteLine " Success colored background" "Contrast" %color_success%
call :WriteLine " Warning colored background" "Contrast" %color_warn%
call :WriteLine " Error colored background" "Contrast" %color_error%

Interesting Points
A challenge in this was outputting text via a CMD shell without a newline. The <var>echo</var>
command, by default, adds a line feed. To output text in a CMD script without including a line feed, simply use:
<NUL set /p ="My string goes here"