When I execute echo -e '\033[49;36m\u2588\033[40;36m\u2588'
in a linux terminal, I get two blocks of the same color:
Here, the first block has no background color (49) while the second block has a black background color. The character displayed should generally take up the entire space, so the background is not visible and they appear the same.
However, if I repeat this in Mac Terminal I get something very surprising:
For some reason, mac terminal is changing the foreground color for different background colors. Through some experimentation, I've found that the foreground color is constant for any fixed background color, and only different for the default background color. The color it renders is distinct from any of the other dim or bright modifications offered by ansi terminals.
Why is this happening, and more importantly, can I fix it?
Best Answer
Short answer: don't use "compound" color codes like
\033[49;36m
, use separated colour instructions like\033[0;42m\033[0;36m
instead. The difference can be nicely seen by comparing the output of those two commands:(note that my version of bash could not process
\u2588
, so I had to resort to the hex variant\xe2\x96\x88
).Suggestion for future code:
Create a file (for example in
~/.bash_color_definitions
) with the following content:And source it on every bash start by putting
source ~/.bash_color_definitions
into your.bashrc
or.bash_profile
. Then start producing more readable code like this:EDIT:
Turns out, the code in my answer actually reset the background (as Erik noted in the comments). After a bit of testing, it appears that the Mac Terminal "mixes" the foreground/background colours a bit different when you try to use color code
49
, i.e. the "default background color".iTerm.app for example does not behave in this way, so you could easily switch terminals, if you want to.
A valid solution, however, is to fully specify the background color (i.e. don't just use
49;36m
, use47;36m
if your background is white). Or better use thexterm-256color
color specifications; that is\033[38;5;___m
for the foreground and\033[48;5;___m
for the background colours (replacing the underscore with a number in 0-255). At least on my computer, this then produces consistent colours:If you want to check which ANSI xterm-256color best matches your actual background color, you could use this script (modified version from the one found here):