ANSI escape sequences consist of a sequence of characters beginning with the Escape character, character 27. The next character is often (though not always) an open-square-bracket: [
The echo command can send escape characters if you specify -e
and use \e
for escape.
The ANSI standard defines 8 colours, plus a bright mode, giving a total of 16 posibilities. The sequence is:
\e[<number>m
Where <number>
is one of:
Foreground:
- 30 Black
- 31 Red
- 32 Green
- 33 Yellow
- 34 Blue
- 35 Magenta
- 36 Cyan
- 37 White
Background:
- 40 Black
- 41 Red
- 42 Green
- 43 Yellow
- 44 Blue
- 45 Magenta
- 46 Cyan
47 White
0 Reset all
- 1 Bold
So to make your foreground red and your background yellow:
$ echo -e "\e[31m\e[43m"
And to enable bold:
$ echo -e "\e[1m"
Of course, you can combine them all together:
$ echo -e "\e[31m\e[43m\e[1m"
There are many many other escape codes for doing other things.
For example - clear the screen and move the cursor to the top-left:
$ echo -e "\e[2J\e[1;1H"
Which is useful when changing the colour:
$ echo -e "\e[31m\e[43m\e[1m\e[2J\e[1;1H"
Which will change the colours, clear the screen, and put the cursor at the top-left. Well, almost the top left. Echo puts a carriage return in, so it moves down a line. You can add -n
to echo to prevent this if you're fussy.
If you mess it all up and can't see what you're typing you can reset the terminal colours to normal by pressing:
Ctrl+v
[
0
m
Return
At what you hope is the command prompt. It will whinge about an unknown command, but you will be able to see what you're doing again.
If you are using console, not an X-server, the colour settings are not controlled by ~/.Xresources. For command-line and curses apps, it is the value of $TERM and the corresponding entries in termcap and terminfo which determine how colours are displayed.
Tmux may complicate things, I haven't tried it so can't advise. I would get things working right without it first.
Best Answer
You don't need a dedicated external program to display colors in your terminal. If the terminal supports colors then it will react to specific control sequences that are nothing more than sequences of bytes embedded in the very same stream that carries text to be printed. You can print such sequences with
echo
or (better) withprintf
or with anything that can print arbitrary data.Many online resources cover a widely spread palette of 8 colors plus 8 bright counterparts (example). Modern terminal emulators additionally support 24-bit color; this is what you need. I assume your terminal emulator is modern enough.
The sequences are:
ESC[38;2;⟨r⟩;⟨g⟩;⟨b⟩m
to set RGB foreground colorESC[48;2;⟨r⟩;⟨g⟩;⟨b⟩m
to set RGB background colorwhere
ESC
denotes the escape character (a byte with decimal value 27, octal 33, hexadecimal 1B),⟨r⟩
,⟨g⟩
and⟨b⟩
are respectively red, green and blue 8-bit components written in decimal using ASCII digits (so the range is 0..255). The standard sequenceESC[0m
orESC[m
can be used to reset the colors (and more in general) to whatever your terminal considers the default.The escape character (
ESC
above) can be denoted as\033
(octal),\0x1B
or\x1b
(hexadecimal),\e
,^[
or in yet another way. Various tools support various subsets of these.An example of how to print a colored text with
printf
from a shell:You want to provide foreground color as a string in a format like
[#FFFFFF]
. If the relevant escape sequence used hexadecimal numbers, it would be relatively easy to convert your desired format to a working escape sequence (e.g. withsed
). Unfortunately the sequence must use decimal representation of RGB components.What you can do easily is to use
%d
ofprintf
to convert hexadecimal to decimal. It will look like this:These
0x00 0xA0 0xFF
need to be separate arguments. It takes some work to get to them from the form of[#00A0FF]
, but it is possible. If your goal is to parse strings in the form of[#FFFFFF]this is white text
, where[#…]
is always at the beginning, then it can be done just by manipulating strings in a POSIX shell (mainly with these). An example shell function:And then:
If you want to detect
[#…]
anywhere in a line and substitute it with a proper escape sequence then a more powerful tool is advised. If not the conversion from hexadecimal to decimal,sed
would do well. Because of the conversion I think you need something more likeawk
. Anyway in principle this seems possible with standard tools. As you "intend to make some kind of program", I won't take this joy away from you by publishing a working example. :) Now you know what to print to the terminal. Good luck!Note a dedicated external program to display colors may go beyond generating escape sequences straightforwardly, like our
colprint
function does. First it may check$TERM
and$COLORTERM
to learn if the terminal really supports colors and how many of them; then it may pick sequences that actually work. E.g. if it discovers the terminal does not support 24-bit color, it may translate the color you want to the closest color of the supported palette.