How I Learned to Tolerate White on Fuscia

Pulling back from the archives this is a repost of a previous blog post. This time ripped from a guest spot at The Nubby Admin, a fantastic blog from a fellow tech nerd.

One of the worst problems I have with tabbed consoles is knowing exactly which console I'm working in. Sure, I can simply look at either the shell's title, or the prompt, but I still inevitably will type a command into the wrong console. Normally this will result in something more akin to "file not found" because you catted the wrong file, rather than "Now running koan on all servers" because you did something in mcollective prod instead of test. While chatting up a guy at work about this problem we threw around changing the background color depending on which system you're on.

This is one of those things that's a little trickier than one might think at first blush. For instance, my first thought was to overload the ssh operator and make the changes client side. This works for me since I use cygwin as my ssh client and proxy through an aggregator (see this ServerFault answer about proxying). My coworker, however, uses puttycm which is a fair bit more restrictive and doesn't allow me to do any kind of local overloading. Largely because of this I was force to push the colorization to the remote host. Colorizing remotely had the advantage of meeting both our use cases but at the expense of requiring changes on every single system we might ssh into.

While I proxy all of my sessions through the jump host he would first log into the jump host and then remote elsewhere. This meant we had to change the background color on login, but then change it back on logoff. Otherwise an accidentally reused session could have incorrect coloring. To that end, I decided to make the colorization a separate function so it could easily be reused.

It's also worth noting that this was designed for a system running bash-3.x. I still deal with a lot of RHEL5 systems, which uses bash-3.x, so I coded to it for maximum compatability. Since associative arrays weren't added until bash-4.x I had to do some odd stuff with the arrays that basically amount to magic.

Without further ado, below is everything you'll need to add to your ~/.bashrc file to make this garbage work. With any luck, the comments are sufficient to explain.

function setcolor {
# Set up the colormap using hex codes for the colors
  colormap=( "node1:#330000"
             "node2:#003300"
             "node3:#330033"
             "node4:#333300"
             "node5:#FF0000"
             "node6:#0000FF" )
# Generate my own short hostname, i.e. turn node1.example.com into node1
  short=`echo ${HOSTNAME} | sed "s/..*$//"`
color="#000000" # Set default color to black
# Iterate through the colormap looking for the hostname. Also, some bash magic.
  for host in ${colormap[@]}; do
    if [[ ${host%%:*} == ${short} ]]; then
      color=${host##*:}
    fi
  done
# Wrap the color in the xterm escape sequences to set the background color
  echo -ne "33]11;${color}07" # Set the background color
}
# Only run the setcolor function if we are using xterm or xterm-color as our termtype
if [ $TERM = "xterm" ]; then
  export TERM="xterm-color"
  setcolor
elif [ $TERM = "xterm-color" ]; then
  setcolor
fi
# Replaces the shell title with the name of the host we are sshing to
function ssh {
echo -ne "33]0;${1}07"     # Set the terminal title to the host we are sshing to
  /usr/bin/ssh $1 $2 $3
  setcolor  # Once ssh exits, reset the color back to what it should be
}