TL;DR: How to add color to text displayed in the command prompt window.
Good Old DOS Prompt
Every once in a while, I find it convenient to use the good old command prompt window, aka the DOS prompt. For example, if a console application takes many arguments, it may be easiest to create a simple batch (.bat) file with the entire command line followed by the pause command. You then simply double click on the batch file to invoke the application on as-needed basis.
Typically console applications provide monochrome output, which makes the display look archaic. Before Windows 10, there was no easy way to display such text in colors (aside from changing foreground and background colors). In Windows 10, the command prompt window got overhauled and now supports control character sequence that can be used to adjust the looks of the window.
Sample Scenario
Let’s assume we have a job (batch file) that calls two console applications, one after another. For simplicity, we will simulate the output from these applications by two other batch files.
@echo off
cls
echo This sample job invokes two tasks, for example .NET console apps.
REM The tasks are simulated by FirstTask.bat and SecondTask.bat batch files
call FirstTask.bat
call SecondTask.bat
echo Both tasks have completed.
pause
REM This is a simulated output from an executable program, e.g. a .NET console application
echo The first task is starting.
echo There were 500 records processed with no errors.
echo The first task has completed processing in 0.001s.
REM This is a simulated output from an executable program, e.g. a .NET console application
echo The second task is starting.
echo Error occurred in record# 344: Invalid record type.
echo There were 500 records processed with 1 error.
echo The second task has completed processing in 0.003s.
When we double-click on out JobWithTwoTasks.bat
file, our job will get executed and we will see this rather boring looking output:
Task Separators
When looking at this last output, it’s difficult to see what happened, in particular which part of the output was produced by which task. It seems as if the best we can do is to add some empty lines to separate sections of the output:
echo.
call FirstTask.bat
echo.
call SecondTask.bat
echo.
Upon making this change to JobWithTwoTasks.bat
, our output looks like this:
Adding Color
When on Windows 10, we can do better. Basically, any part of the display can have it’s own color. So, if we add some special characters to the output:
REM Set text color to green
echo [0;92m
call FirstTask.bat
REM Set text color to yellow
echo [0;93m
call SecondTask.bat
REM Reset text color
echo [0m
, then the output from the first will show in green and the output from the second task will show in yellow:
Some explanation is in order here. The mysterious character is the escape character with an ASCII code of 27 (decimal). Depending on the editor you’re using to edit the JobWithTwoTasks.bat
file, it may be more or less challenging to enter this special character. Perhaps, the easiest approach is to use the clipboard, i.e. copy and paste. For example, it can copied directly from this page.
We’re also seeing some strange sequences following the escape character. How do we know that using [0;92m
will set our text color to green? There are a few resources that you may need to google for. I found this file provided by Michele Locati very helpful. It makes the selection of a proper character sequence a breeze.
The basic idea is that each sequence starts with the escape character followed by an open bracket. It then contains up to 16 parameters separated by semicolons. The sequence ends with an m
character. So, for example, our [0;92m
contains 2 parameters: 0 means “reset the console to its original state” and 92 means “set text color to green”. The first parameter (0) is relevant in cases where text attributes other than color (e.g. underline) have been set previously. Feel free to experiment with different control character sequences.
No Extra Lines
Now that the tasks are displayed in different colors, we may no longer want the blank lines between them. To eliminate these extra lines, we need the echo
command to suppress the line-feed character at end. There is a fairly known trick to do that:
REM Set text color to green
echo | set /p=[0;92m
call FirstTask.bat
REM Set text color to yellow
echo | set /p=[0;93m
call SecondTask.bat
REM Reset text color
echo | set /p=[0m
A quick explanation on this trick in which the output from echo
command is “piped” into the set
command. The control character sequences are sent as a prompt by the set
command, which expects an entry to be made to the console. This prompt is immediately satisfied by the line-feed character provided by the echo
command and importantly the line-feed is not echoed to the screen. If you’re curious what variable is being set by the set
command above, the answer is none. While it is OK to leave off the variable name (the part between /p
and the equal sign), no variable is set in this case. But, we’re veering off topic here.
Now our output looks like the original one, but in color:
Refinements
We now have the output we want, but our code can still be refined. All revisions presented below will result in the same output as on the last image above.
First, using echo
and piping to supply data requested by set
command is awkward and inefficient. Piping can be avoided by instead having set
read from nul
, i.e. a special device that yields EOF (end of file) immediately. So, our code might look like this instead (and still produce identical output):
REM Set text color to green
<nul set /p=[0;92m
call FirstTask.bat
REM Set text color to yellow
<nul set /p=[0;93m
call SecondTask.bat
REM Reset text color
<nul set /p=[0m
You may not like the fact that a non-printable character (, i.e. escape) is proliferated throughout the script. We can make our code easier to read by assigning the escape characters to a variable and using this variable afterwards. The code below again provides the same output as before.
REM ESC character (Ascii code 27)
set esc=
REM Set text color to green
<nul set /p=%esc%[0;92m
call FirstTask.bat
REM Set text color to yellow
<nul set /p=%esc%[0;93m
call SecondTask.bat
REM Reset text color
<nul set /p=%esc%[0m
What if you don’t like the escape character to be present in your script at all? It can be done too! Something like this:
call SetTextColor green
call FirstTask.bat
call SetTextColor yellow
call SecondTask.bat
call SetTextColor
We have now delegated handling of the control character sequences to another batch file: SetTextColor.bat
. Here is what it looks like:
@echo off
REM A script to set the color of text printed to the console.
REM Intended to be called from other .bat files like so:
REM call SetTextColor <color>
REM , where <color> is one of: red, green, yellow, blue, magenta, cyan, white
REM ESC character (Ascii code 27)
set esc=
If "%1" == "red" (
<nul set /p=%esc%[0;91m
goto done
)
If "%1" == "green" (
<nul set /p=%esc%[0;92m
goto done
)
If "%1" == "yellow" (
<nul set /p=%esc%[0;93m
goto done
)
If "%1" == "blue" (
<nul set /p=%esc%[0;38;2;64;128;255m
goto done
)
)
If "%1" == "magenta" (
<nul set /p=%esc%[0;95m
goto done
)
)
If "%1" == "cyan" (
<nul set /p=%esc%[0;96m
goto done
)
)
If "%1" == "white" (
<nul set /p=%esc%[0;97m
goto done
)
REM TODO: add other colors and/or display attributes as needed
REM If color is unrecognized or omitted, then reset color (back to the console original).
<nul set /p=%esc%[0m
:done
The script can be expanded to support additional colors and text attributes, such as underline. Feel free to experiment with different control character sequences.
Conclusion
Windows 10 allows control over color and other display attributes in the command prompt window. This makes it possible for DOS batch scripts to output text looking just like output from modern tools, such as PowerShell or Linux scripts.
Source Code
The scripts presented in this article is available on GitHub in this repository.