SSH Environment Specific Terminal Background Colors

How many times have you logged into a server environment and had to run a few commands, only to discover that you were in fact logged into the wrong server? Hopefully not very many times, because as I have learned the results can be painful (if not catostrophic).

I recently read this blog post that discusses setting an environment specific background color depending on the name of the server being ssh'd into. I was very interested in using this approach as an additional safety check when working with various servers and environments that I am required to interact with on a daily basis. Unfortunately, the provided solution is Mac specific, so I decided to implement a solution that would work for me on Linux.

The main criteria for this solution are that it works on Linux and plays nicely with tmux, given that I perform pretty much all of my command line work inside of tmux sessions. Additionally, I decided to tackle this using ZSH since it's my shell of choice, however this should work pretty easily in BASH as well with slight modifications.

To start, I decided to implement a simple script that would allow me to change the color of the terminal based on an identifier provided to the script. This was pretty simple to do, given how easy it is to change the background color of any xterm compatible terminal by simply printing specific codes. Additionally, after a bit of experimentation I found that I could easily modify the background color of the current tmux pane using tmux select-pane. To perform this task, I implemented a shell script I simply call colorterm.sh :

#!/bin/sh
if [[ "$TERM" = "screen"* ]] && [[ -n "$TMUX" ]]; then
  if [ "$1" == "prod" ]; then
    tmux select-pane -P 'bg=#331C1F'
  elif [ "$1" == "dev" ]; then
    tmux select-pane -P 'bg=#192436'
  elif [ "$1" == "other" ]; then
    tmux select-pane -P 'bg=#253320'
  else
    tmux select-pane -P 'bg=#282c34'
  fi;
else
  if [ "$1" == "prod" ]; then
    printf '\033]11;#331C1F\007'
  elif [ "$1" == "dev" ]; then
    printf '\033]11;#192436\007'
  elif [ "$1" == "other" ]; then
    printf '\033]11;#253320\007'
  else
    printf '\033]11;#282c34\007'
  fi
fi

There are a couple of things to notice about this script.

  1. Different colors are selected based on which identifier is passed in. I use prod, dev, other, and none. I use the none case to reset to the default color
  2. These colors rely on the terminal having 24bit color capability. You can use this with 256 colors, but the result doesn't look very appealing as it's difficult to find colors dark enough for a background.
  3. If we're inside a tmux session we run tmux specific commands to set the current pane's background color.

Now we can simply run the script to change the color of our terminal using one of the identifiers:

Right, now we can use this script to create a function that will wrap ssh and automatically change the background color of the terminal whenever we ssh into a server. The only slight catch is that we need to setup a trap that will set the terminal color back to the default upon completion of the function (and the ssh session).

color-ssh() {
    trap "colorterm.sh" INT EXIT
    if [[ "$*" =~ "prod" ]]; then
        colorterm.sh prod
    elif [[ "$*" =~ "dev" ]]; then
        colorterm.sh dev
    else
        colorterm.sh other
    fi
    ssh $*
}

This rather simple function starts out by setting up a trap that will execute when the function completes. Upon completion, the colorterm.sh script with be executed with no parameters setting the terminal background to the default color. Next we inspect the parameters passed to the function to see if there is a match for either prod, dev, or neither, and pass the appropriate identifier to the colorterm.sh script. Depending on the scenario, these checks could be made much more complex than they are and a wider range of colors and identifiers could be employed. Finally, we defer to ssh and pass along any parameters provided to the current function.

That's mostly all there is to it! All that's left to do is setup the proper completions and the alias:

compdef _ssh color-ssh=ssh
alias ssh=color-ssh

Now when we invoke ssh it will change the background color of the terminal (or tmux pane) based on the server name being accessed. You can see it in action here:

And that's all there is to it! This can be easily modified to work for more environments by customizing the matching statements used in color-ssh and the identifiers used to select colors in colorterm.sh. I recommend pairing this with an ssh config file that can be used to create aliases for each server that you can tack identifiers onto like -prod or -dev.

Anyways, thanks for reading this post. I hope that someone found it useful.

Share Comments
comments powered by Disqus