Growing with the Web

Colours and formatting in Gnome/Ubuntu's Terminal

Published
Tags:

This article dives deep into the colours, formatting and customisation of gnome-terminal, the default bash terminal for Ubuntu. The majority of this article applies to many terminal variants, not only to Gnome/Ubuntu.

Colours

The terminal has a colour scheme which is makes available to various applications like bash and vim. There are several colours within the colour scheme available as follows:

  • 0 - Black
  • 1 - Red
  • 2 - Green
  • 3 - Brown/yellow
  • 4 - Blue
  • 5 - Purple
  • 6 - Cyan
  • 7 - Light grey/white
  • 9 - Default

Printing coloured messages

Foreground

echo can be used to print coloured messages to the terminal by providing the -e flag which enables escape sequences. First you need to escape the text which can be done using either "\e[", "\033[" or "\x1B". Then add the 3 character which indicates foreground colour, then the colour code, and finally the m character to finalise the escape sequence.

echo -e "\e[31mred"

You should always remember to reset the text back to its normal state at the end of the message or the following messages to the terminal could be printed as red, reseting can be done with the escape sequence "\e[0m".

echo -e "\e[31mred\e[0m default"
echo -e "\e[31mred \e[34mblue\e[0m"

Background

The background colour can also be specified, this is done by substituting the 3 (colour type) before the colour code with 4.

echo -e "\e[41mred bg\e[0m default"
echo -e "\e[41m\e[36mcyan fg on red bg\e[0m"
echo -e "\e[46m\e[31mred fg on cyan bg\e[0m"

Combining rules

There is not need to provide multiple escape sequences when providing both a foreground and a background colour, the semi-colon ; character enables multiple colour rules to be specified within a single escape sequence.

echo -e "\e[41;36mcyan fg on red bg\e[0m"
echo -e "\e[46;31mred fg on cyan bg\e[0m"

Light colour variants

Each colour has a light variant that can be used, black becomes dark grey, light grey becomes white, etc. This can be used for foreground by using 9 instead of 3 and for background by using 10 instead of 4.

echo -e "\e[101;96mlight cyan fg on light red bg\e[0m"
echo -e "\e[106;91mlight red fg on light cyan bg\e[0m"

Formatting

The terminal is not limited to customising colours, there are a bunch of different formats that can be applied to the text as well. Above we used the reset formatting flag 0 to reset the text style used previously. Here are other formats available:

  • 0 - Reset
  • 1 - Bold/light
  • 2 - Dim
  • 3 - Italic
  • 4 - Underline
  • 5 - Blink (not widely implemented)
  • 7 - Reverse (invert foreground and background colours)
  • 8 - Hidden (typically used for passwords)
  • 9 - Strikethrough
echo -e "\e[1mbold\e[0m"
echo -e "\e[2mdim\e[0m"
echo -e "\e[3mitalic\e[0m"
echo -e "\e[4munderline\e[0m"
echo -e "\e[5mblink\e[0m"
echo -e "\e[7mreverse\e[0m"
echo -e "\e[8mhidden\e[0m"
echo -e "\e[9mstrikethrough\e[0m"

Combining formats

Just like colours, formats can be combined with other formats by separating them with a semi-colon.

echo -e "\e[2;3;4mdim italic underline\e[0m"
echo -e "\e[1;9mbold strikethrough\e[0m"
echo -e "\e[3;7mitalic reverse\e[0m"
echo -e "\e[1;3;7;31mbold italic reverse red\e[0m"

Configuring the terminal’s colour scheme via the UI

Configuring the colour scheme through the UI in Ubuntu is fairly simple. Launch the terminal, go to Edit -> Profile Preferences and open the Colors tab. That opens this window where the colour scheme can be configured as desired for the current profile.

Automating colour scheme configuration via the command line

< Gnome 3.8

Gconf is like the registry in gnome, it’s a set of %gconf.xml files across multiple directories within ~/.gconf/ that store the configuration of certain applications in the OS. This is where the terminal’s colour scheme is stored, specifically in ~/.gconf/apps/gnome-terminal/profiles/<profile>/%gconf.xml.

You cannot write directly to these files and expect the properties to propagate to the applications as the operating system caches the values in memory and periodically writes them back to the file so changes carry over on restart. Instead there is a command line tool aptly named gconftool-2 that can be used to set each key-value pair individually.

To set a value using gconftool-2, call it by providing the value, the --set argument which takes a key and the --type argument which sets the value type (string, bool, etc.).

gconftool-2 --set <key> --type string <value>

The easiest way I’ve found to create a script that sets up your colour scheme is to do the initial configuration through the UI and then copy the values over from ~/.gconf/apps/gnome-terminal/profiles/Default/%gconf.xml. Here is my current setup:

gconftool-2 --set "/apps/gnome-terminal/profiles/Default/bold_color_same_as_fg" \
    --type bool "true"
gconftool-2 --set "/apps/gnome-terminal/profiles/Default/use_theme_colors" \
    --type bool "false"
gconftool-2 --set "/apps/gnome-terminal/profiles/Default/background_darkness" \
    --type float "0.93776822090148926"
gconftool-2 --set "/apps/gnome-terminal/profiles/Default/background_type" \
    --type string "transparent"
gconftool-2 --set "/apps/gnome-terminal/profiles/Default/palette" \
    --type string "#096209620962:#E6E61A1A4141:#1717E3E38584:#FFFFDEDE6A6A:#4F4F8584FFFF:#A0A07474C4C4:#4F4FA5A5C7C7:#D3D3D7D7CFCF:#404040404040:#CFCF18173A39:#0D0DC7C77272:#F4F4CDCD4545:#26265D5DD9D9:#88884E4EBABA:#2F2F62627777:#EEEEEEEEECEC"
gconftool-2 --set "/apps/gnome-terminal/profiles/Default/alternate_screen_scroll" \
    --type bool "true"
gconftool-2 --set "/apps/gnome-terminal/profiles/Default/background_color" \
    --type string "#151517161818"
gconftool-2 --set "/apps/gnome-terminal/profiles/Default/visible_name" \
    --type string "Default"
gconftool-2 --set "/apps/gnome-terminal/profiles/Default/bold_color" \
    --type string "#000000000000"
gconftool-2 --set "/apps/gnome-terminal/profiles/Default/foreground_color" \
    --type string "#FEFEFEFEFEFE"

Gnome 3.8+

In Gnome 3.8 and above you customise gnome-terminal using dconf, like so:

# This should be "Default"
profile_id=b1dcc9dd-5262-4d8d-a863-c897e6d979b9

dconf write /org/gnome/terminal/legacy/profiles:/:$profile_id/bold-color-same-as-fg "true"
dconf write /org/gnome/terminal/legacy/profiles:/:$profile_id/use-theme-colors "false"
dconf write /org/gnome/terminal/legacy/profiles:/:$profile_id/background-transparency-percent "0"
dconf write /org/gnome/terminal/legacy/profiles:/:$profile_id/use-transparent-background "true"
dconf write /org/gnome/terminal/legacy/profiles:/:$profile_id/palette "['rgb(9,9,9)', 'rgb(230,127,146)', 'rgb(125,227,180)', 'rgb(255,231,145)', 'rgb(140,175,255)', 'rgb(173,145,196)', 'rgb(109,174,199)', 'rgb(198,202,194)', 'rgb(155,158,152)', 'rgb(230,81,109)', 'rgb(79,227,159)', 'rgb(255,219,94)', 'rgb(89,140,255)', 'rgb(155,106,196)', 'rgb(70,162,199)', 'rgb(238,238,236)']"
dconf write /org/gnome/terminal/legacy/profiles:/:$profile_id/background-color "'#151517161818'"
dconf write /org/gnome/terminal/legacy/profiles:/:$profile_id/visible-name "'Default'"
dconf write /org/gnome/terminal/legacy/profiles:/:$profile_id/bold-color "'#000000000000'"
dconf write /org/gnome/terminal/legacy/profiles:/:$profile_id/foreground-color "'#FEFEFEFEFEFE'"
dconf write /org/gnome/terminal/legacy/profiles:/:$profile_id/background-color "'#151517161818'"
dconf write /org/gnome/terminal/legacy/profiles:/:$profile_id/use-theme-transparency "false"
dconf write /org/gnome/terminal/legacy/profiles:/:$profile_id/font "'Hack 11'"

Additional colours

Certain terminals support an additional 256 colours that can be used in addition to the ones defined in the colour scheme. This is done using the escape sequence "\e[38;5;<color_number>m".

echo -e "\e[38;5;1mColor #1 fg\e[0m"
echo -e "\e[38;5;128mColor #128 fg\e[0m"
echo -e "\e[38;5;256mColor #256 fg\e[0m"
echo -e "\e[48;5;1mColor #1 bg\e[0m"
echo -e "\e[48;5;128mColor #128 bg\e[0m"
echo -e "\e[48;5;256mColor #256 bg\e[0m"

Typically when writing terminal apps you will want to stick with the colours provided by the colour scheme. This will ensure that your application fits in to the colours that the user is used to.

Useful scripts

This handy script by Sam Hocevar prints all colour combinations to the terminal.

#!/bin/bash
#Background
for clbg in {40..47} {100..107} 49 ; do
  #Foreground
  for clfg in {30..37} {90..97} 39 ; do
    #Formatting
    for attr in 0 1 2 4 5 7 ; do
      #Print the result
      echo -en "\e[${attr};${clbg};${clfg}m ^[${attr};${clbg};${clfg}m \e[0m"
    done
    echo #Newline
  done
done

A more compact version of the above by Daniel Crisman, printing only main colours used.

#!/bin/bash
T='●●●'
echo -e "\n                 40m     41m     42m     43m\
     44m     45m     46m     47m";
for FGs in '    m' '   1m' '  30m' '1;30m' '  31m' '1;31m' '  32m' \
           '1;32m' '  33m' '1;33m' '  34m' '1;34m' '  35m' '1;35m' \
           '  36m' '1;36m' '  37m' '1;37m';
  do FG=${FGs// /}
  echo -en " $FGs \033[$FG  $T  "
  for BG in 40m 41m 42m 43m 44m 45m 46m 47m;
    do echo -en "$EINS \033[$FG\033[$BG  $T  \033[0m";
  done
  echo;
done
echo

This script by Sam Hocevar prints all 256 colours to the terminal as both foreground and background.

#!/bin/bash
for fgbg in 38 48 ; do #Foreground/Background
  for color in {0..256} ; do #Colors
    #Display the color
    echo -en "\e[${fgbg};5;${color}m ${color}\t\e[0m"
    #Display 10 colors per lines
    if [ $((($color + 1) % 10)) == 0 ] ; then
      echo #New line
    fi
  done
  echo #New line
done

Like this article?
Subscribe for more!