Published in Articles on by Michiel van Oosterhout ~ 5 min read
In the previous article we learned that the Git for Windows distribution is based on MSYS2, a POSIX-like environment for Windows, and comes with additional software, including the Bash command-line shell. In this article we will start the work of configuring this installation of Bash. The ultimate goal is to configure a custom prompt. The first step towards that goal is to make it easy to change the colors of the output.
Colors in Bash
Git for Windows does not include a terminal, so its installation of Bash (added to the Start menu as Git Bash) runs in Windows' default terminal, which is either the traditional Console Window Host or the newer Windows Terminal (see The Windows command-line interface, part 2).
Bash, being an implementation of the POSIX shell, does not use Windows' Console API. Instead it relies on terminal sequences for things like colored output. These sequences start with the ESC
control code, and are not so easy to type.
In Bash, input is handled by the Readline library, a library for line-editing. To type the ESC
control code in Bash we must first use the quoted-insert Readline command, which by default is bound to Ctrl+V. This command signals that the next keypress should be interpreted verbatim. Typing Esc now will result in the ESC
control code. This is how you can enter echo '^[[41;97mTEST^[[0m'
to test a terminal sequence.
Alternatively we can use ANSI-C quoting which replaces \e
with the ESC
control code, so we can enter echo $'\e[41;97mTEST\e[0m'
.
Finally, instead of an ANSI-C quoted string, the echo
command's -e
option can also be used to replace \e
with the ESC
control code, so we can enter echo -e '\e[41;97mTEST\e[0m'
.

A color
function for Bash
Windows Command Processor has a builtin color
command to change the background and foreground colors of the entire buffer. This command expects colors to be specified using color palette entry numbers.

color
command in Windows Command Processor
We can create a color
function for Bash. But instead of changing the colors of the entire buffer, it will just output a terminal sequence to change the colors of the output immediately following the call to color
. And instead of palette entry numbers, it will accept a letter for each color (r
, g
, b
, c
, m
, y
, k
, and w
) , as well as 0
for the default color, and -
for the terminal's separate background color.
The Windows PowerShell script below creates a Bash file that, when sourced in a Bash session, makes the color
function available.
# Set an environment variable for the terminal's background color
cmd /c setx TERM_BACKGROUND_COLOR "14;16;25"
cmd /c setx TERM_FOREGROUND_COLOR "255;250;244"
# Declare the Bash script contents
$script = @'
# Set background and foreground color
function color {
# Colors (normal and bright)
declare -A colors=(
[k]=0 [r]=1 [g]=2 [y]=3 [b]=4 [m]=5 [c]=6 [w]=7
[K]=60 [R]=61 [G]=62 [Y]=63 [B]=64 [M]=65 [C]=66 [W]=67
[0]=9
)
# Start the SGR terminal sequence
local seq=$'\e['
# Parse background color
local bg=${1:0:1}
if [ $bg = - ]; then
# Parameters for RGB color
seq+="48;2;$TERM_BACKGROUND_COLOR"
elif [ $bg = + ]; then
# Parameters for RGB color
seq+="48;2;$TERM_FOREGROUND_COLOR"
else
# Parameter for palette-based background color
seq+=$(( ${colors[$bg]} + 40 ))
fi
# Separate the parameters for background color and foreground color
seq+=';'
# Parse foreground color
local fg=${1:1:1}
if [ $fg = - ]; then
# Parameters for RGB color
seq+="38;2;$TERM_BACKGROUND_COLOR"
elif [ $fg = + ]; then
# Parameters for RGB color
seq+="38;2;$TERM_FOREGROUND_COLOR"
else
# Parameter for palette-based foreground color
seq+=$(( ${colors[$fg]} + 30 ))
fi
# Finish the SGR terminal sequence
seq+=m
# Output the SGR terminal sequence
echo -n $seq
}
'@
# Ensure the directory exists
$path = "$Env:LOCALAPPDATA\Commando\Color"
$_ = New-Item $path -Force -ItemType Directory
# Create the Bash script
$path = "$path\color.bash"
Set-Content -Path $path -Value $script
# Ensure proper line endings
((Get-Content $path) -join "`n") + "`n" | Set-Content -NoNewline $path
To use the function, source the script in a Git Bash session: . $LOCALAPPDATA/Commando/Color/color.bash
and then call the function, e.g. color rW
to set the background color to red and the foreground color to bright white.

color
function to output SGR terminal sequences in Git Bash
Conclusion
Remembering and typing terminal sequences to change output colors (^[[41;67m
) can be quite difficult. A relative simple Bash script can provide a more intuitive function instead (color rW
), and works in Git Bash, Cygwin's Bash, and even WSL.
Updates
- Added support for
+
to specify the terminal's custom foreground color.