I find it very productive working in a terminal environment, as it's efficient and flexible to deal with processes and data, especially text, and especially on remote machines.

Now terminals have advanced in capability over time, with some form of "xterm" being the usual terminal of choice. Therefore one should not restrict programs to their usual monochrome defaults, as colour can be used to greatly ease the parsing of text by humans. We have dedicated sensors and portions of the brain specifically for colour, so we should not ignore them.

It's a pity that most programs don't enable colours automatically when available, requiring the user to explicitly configure them to do so. Though I am starting to notice newer commands like "htop" for example use colours by default when possible, which is a much more sensible approach given the capabilities of terminals today.

Note I'm not going to describe colour settings that most people know about already. Please see my .bashrc for things like highlighting the shell prompt, or an alias for colouring output from the "ls" command for example.

Available colours

ANSI colours

The standard set of "ANSI" colours available, as output by this simple script, are shown below. Note these colours are indexes into a palette, with those shown being the standard linux palette. This is quite a rich set of colours which lots of applications support, and can be used to highlight text in many useful ways, some of which I'll detail below. (Note I wrote another simple script to convert ANSI colour codes to HTML for display here).
     30    30;47    30;40    30;41    30;42    30;43    30;44    30;45    30;46 
   1;30  1;30;47  1;30;40  1;30;41  1;30;42  1;30;43  1;30;44  1;30;45  1;30;46 
     37    37;47    37;40    37;41    37;42    37;43    37;44    37;45    37;46 
   1;37  1;37;47  1;37;40  1;37;41  1;37;42  1;37;43  1;37;44  1;37;45  1;37;46 
     31    31;47    31;40    31;41    31;42    31;43    31;44    31;45    31;46 
   1;31  1;31;47  1;31;40  1;31;41  1;31;42  1;31;43  1;31;44  1;31;45  1;31;46 
     32    32;47    32;40    32;41    32;42    32;43    32;44    32;45    32;46 
   1;32  1;32;47  1;32;40  1;32;41  1;32;42  1;32;43  1;32;44  1;32;45  1;32;46 
     33    33;47    33;40    33;41    33;42    33;43    33;44    33;45    33;46 
   1;33  1;33;47  1;33;40  1;33;41  1;33;42  1;33;43  1;33;44  1;33;45  1;33;46 
     34    34;47    34;40    34;41    34;42    34;43    34;44    34;45    34;46 
   1;34  1;34;47  1;34;40  1;34;41  1;34;42  1;34;43  1;34;44  1;34;45  1;34;46 
     35    35;47    35;40    35;41    35;42    35;43    35;44    35;45    35;46 
   1;35  1;35;47  1;35;40  1;35;41  1;35;42  1;35;43  1;35;44  1;35;45  1;35;46 
     36    36;47    36;40    36;41    36;42    36;43    36;44    36;45    36;46 
   1;36  1;36;47  1;36;40  1;36;41  1;36;42  1;36;43  1;36;44  1;36;45  1;36;46 

256 colours

"xterm", "konsole" and "gnome-terminal" on my Fedora 8 distribution at least, support 256 colours. [Update Oct 2012: Fedora 18 enables 256 colours by default, and the 256 colour feature page details all of the supported terminals, and a setup script to enable 256 colours for those terminals]. To configure applications to use 256 colours when available, just set the TERM environment variable to xterm-256color, which I do in my .bashrc. Note ubuntu/debian users, ensure you have the ncurses-term package installed which defines the xterm-256color terminal parameters. This means unfortunately that that package must also be installed on any remote machines you log into, or otherwise you'll need to reset your TERM variable to "xterm" there. Note also that if you have a /etc/DIR_COLORS or ~/.dir_colors file, then for ls to colourise the output correctly, you'll need a TERM xterm-256color entry in those files. [Update Feb 2022: coreutils 9.1 will have support to directly show configured ls colours with dircolors --print-ls-colors. Here is an example of --print-ls-colors output]. [Update Dec 2009: I've updated my ansi2html script to support 256 colours, and running a 256 colour palette generator through it we get...
System colors:
                
                
Color cube, 6x6x6:
                                                                              
                                                                              
                                                                              
                                                                              
                                                                              
                                                                              
Grayscale ramp:
                                                
You can hover over the palette above to get the number to use in the 38;5;$number code. Note the default xterm palette is displayed above, but any of the RGB values can be changed and that is also demonstrated in the referenced palette generating script.]

One application I use all the time, which supports 256 colours "out of the box" is VIM, and you can see the difference between 16 and 256 colours with the default colour scheme below:
Note you can hover over the screenshots above to see how the 8 colour version requires extensive use of the "bold" attribute to get the desired colours. The 256 colour version doesn't need to use "bold" for this, but unfortunately it does for certain highlighted items. I always disable the display of bold text anyway in my xterm settings as I think it looks terrible.

RGB colors

Specifying arbitrary RGB colours is possible in some terminal emulators, though not that useful really with character cell resolutions. To specify RGB colours you use 38;2;$R;$G;$B SGR codes. konsole supports RGB for a long time, while xterm supports RGB since Oct 2012, by mapping the RGB codes to the nearest entry in the 256 color palette.

[Update Jan 2017: There was recently a good summary of the state of true colour support in various terminals]

Dark backgrounds

It's also worth noting here that I use terminals with a dark background. Current linux distributions default to light backgrounds so it's sometimes necessary to tweak program settings accordingly which I've detailed before.

Highlighting searches

When searching through text it's very useful to highlight the specific thing you're searching for. To that end, the "grep" command now supports the --color option which I enable by default using an alias in my .bashrc file. I find this extremely useful and had even created a sedgrep script before this became available in grep itself. Note sed is really a superset of grep, and I use it in the scripts presented below to apply colours based on various matches. Here are what grep searches look like with my alias in place:
laptop:~$ look '' | grep [^-]colour$
bicolour
concolour
decolour
discolour
encolour
miscolour
offcolour
overcolour
precolour
recolour
transcolour
tricolour
unicolour
versicolour
watercolour

Colouring logs

There are many programs available to colour logs like grc or logtool, as it is very useful to highlight particular info in log files, or to colour various fields to aid in parsing logs. Note grc is a python program, and I also noticed the terminfo.py module which looks useful for applying colour attributes portably to a terminal. The example below is from my script using similar techniques which I wrote to view web server requests from access_log as they occur. It both filters out insignificant entries and highlights the referrer column which greatly eases the parsing of this information.
webserver:~$ . tail_access_log

 XX.105.176.171 "GET /settings/.bashrc" 200 1438 "google.ro (+bashrc+color)"
 XX.240.229.191 "GET /cmdline.html" 200 11625 "google.co.uk (linux+commands)"
   XX.47.208.50 "GET /cmdline.html" 200 11625 "-"
 XX.254.119.241 "GET /programs/dvd-vr/" 200 4294 "google.com (dvd+vr+format)"
XXX.236.193.195 "GET /ms_mirth/ms57.jpg" 403 976 "http://www.ipmart-forum.com
   XX.142.24.85 "GET /docs/disk/" 200 7826 "google.com (default+grub+layout)"
   XX.148.4.144 "GET /fslint/" 200 5153 "google.de (fslint)"
    XX.113.40.1 "GET /vim.tips.html" 200 6329 "google.com (vim+commands)"
   XX.104.7.126 "GET /settings/gvim/" 200 3985 "google.com (vimrc+highlight)"

Viewing file differences

Actually I've previously described GUI programs being a bit better for viewing file differences, but using colour when at the terminal really does help a lot. To this end I've created an idiff script for reviewing patches interactively. This script is also a good demonstration of how to portably apply colour as it uses the terminfo database to output the correct codes for the terminal, if in fact it does support colour at all. One can invoke it like diff, passing it source files to compare, or instead, filter an existing patch through it as demonstrated below.
laptop:~$ idiff grep-multibyte-color.diff

The --color option messes up UTF8 output. Compare the following:

echo "útf8" | LANG=C grep --color=always -E '[ -~]'
echo "útf8" | LANG=C grep --color=always -E '[^ -~]'

Note those regular expressions match ascii and
non ascii data respectively. The second one in
particular is useful for highlighting UTF8 characters.

It was pointed out to me later that '+' can
be used to highlight all adjacent non ASCII bytes.
I.E the following patch is useful only to minimize
the number of colour codes output, and the non printable
ASCII matching can be done like this for UTF-8:

echo "útf8" | LANG=C grep --color=always '[^ -~]\+'

--- grep.c.orig	2005-12-09 17:37:35.000000000 +0000
+++ grep.c	2005-12-12 14:36:42.000000000 +0000
@@ -839,17 +852,21 @@
 		  cur = mid;
 		  mid = NULL;
 		}
-	      fwrite (cur, sizeof (char), b - cur, stdout);
+	      if (b - cur) {
+		MATCH_COLOR_END();
+		fwrite (cur, sizeof (char), b - cur, stdout);
+              }
 	    }
 
-	  PR_SGR_START_IF(match_color);
+	  MATCH_COLOR_START();
 	  fwrite (b, sizeof (char), match_size, stdout);
-	  PR_SGR_END_IF(match_color);
-	  if (only_matching)
+	  if (only_matching) {
 	    fputs("\n", stdout);
+	  }
 	}
       cur = b + match_size;
     }
+    MATCH_COLOR_END();
 
   if (buf)
     free(buf);	/* XXX */

Highlighting status of whole command line

One thing worth highlighting in my .bashrc is how I color my prompt to show the full exit status for all components of the previous command. I do this with
PS1="[\[\033[1;31m\]\${PIPESTATUS[@]/#0/\[\033[0m\]"\
"\[\033[1;32m\]0\[\033[1;31m\]}\[\033[0m\]] \w$ "
with an example run being:
[0] ~$ true | false | true
[0 1 0] ~$

Some fun

You can paste the following into a terminal to get a stupid matrix like screensaver, or for an infinitely better example, see cmatrix.
tr -c "[:xdigit:]" " " < /dev/urandom | dd cbs=$COLUMNS conv=unblock |
GREP_COLOR="1;32" grep --color "[^ ]"
For a silly 256 colour demo here is a command line to cycle through all shades of gray
yes "$(seq 232 255;seq 254 -1 233)" |
while read i; do printf "\x1b[48;5;${i}m\n"; sleep .01; done
Note also the venerable game 0verkill, and the Colour AsCii Art library, which is included with mplayer for example:
mplayer -vo caca video.mpg
© Apr 23 2008