The linux console is tighed to 16 colors (or 8 depending on the setup), but something I didn’t know, is that you can choose them through the whole bunch of 256 colors. Linux has escape sequences to change those if it has been enabled in the kernel.
The escape sequences
The format is simple once you know it, and you can find them all in the console codes manual page: (in ESC- but not CSI-sequences
section)
<ESC>]P{index}{hex red}{hex green}{hex blue}
Where index
is the set of ANSI colors:
0
black and foreground1
dark red2
dark green3
brown4
dark blue5
purple6
dark cyan7
light gray8
dark gray9
redA
(10) greenB
(11) yellowC
(12) blueD
(13) magentaE
(14) cyanF
(15) white and foreground
Then RGB components are specified in hexadecimal values. So changing the background color (0) to #222222
is as simple as echo’ing:
$ echo -en '\e]P0222222`
A clear is necessary after setting colors because existing characters are not modified. That’s what I have put in my login startup script:
if [ "$TERM" = 'linux' ]; then
# set custom colors on ttys
concol() { echo -en "\e]P$1$2$3$4"; }
concol 0 2f 34 3f # black/background
concol 1 a9 63 5d # dark red
concol 2 46 84 59 # dark green
concol 3 84 76 3d # brown
concol 4 58 79 af # dark blue
concol 5 9c 65 94 # purple
concol 6 00 85 92 # dark cyan
concol 7 d8 d8 d8 # light gray
concol 8 77 77 77 # dark gray
concol 9 ff bb b2 # red
concol A 9d de af # green
concol B e0 ce 91 # yellow
concol C b3 d1 ff # blue
concol D fa bd f0 # magenta
concol E 79 e0 ed # cyan
concol F ff ff ff # white/foreground
clear
fi
Here is the result of dircolors --print-ls-colors
(yes, the background is the same colors than my blog pages background ^^):
And before login?
That works once you logged in, but until there you’re stuck with default ones. The solution is to use the issue display from agetty
which shows text before the login prompt. I am more used to have a clean and empty screen for login, so my agetty
run command usually has the --noissue
argument, but putting only an escape sequence gives the same effect:
# from your services manager (mine is dinit)
$ agetty --nonewline --nohints --nohostname linux
With the following /etc/issue
:
\e]P02f343f\e[H\e[J
Where \e[H
moves cursor to the origin of the screen and \e[J
erases all from the cursor.
I also keep the login
program ending in timeout and relaunching when needed on other ttys:
# from your services manager
$ agetty --nonewline --login-pause --timeout 10 --nohints --nohostname linux
And from boot?
There is a way to enable this as soon as the ramdisk is loaded, by echo’ing the right sequence in a script included in the initrd, but as my startup is really fast (1 second or 2) I thought it was not worth trying it.