Adding Solarized Colors to Bash Scripts

Solarized is one of the most beloved, most supported terminal color themes in the world. It is supported as one of the main terminal color scheme options in the Gnome Terminal without any additional installation. Properly configured a Solarized terminal can save you hours of eye strain and pain. Here’s how to add Solarized colors easily to all your Bash scripts, including your .bashrc for use in your prompt.

Step by Step

Navigate to an existing project repo or create a new one.

Create a new file called solarized.bash to hold your code.

touch solarized.bash

Open the file for editing and add the following.

# source me (don't execute me)

magenta='\033[0;35m'

⚠️ That’s a backslash \ (not a forward slash), a semi-colon ; (not a colon), and a lower-case m (not upper).

Save your changes.

Open up a terminal in this directory.

This is just one color to get the idea.

All the strange characters are part of the ANSI terminal escape sequences, which tell your terminal to change colors for everything printed to it from that point on.

Now let’s try to use it by sourcing it from the shell. Remember you can either use . to source or the word source. I tend to use source in scripts and . from the command line because it is quicker.

. solarized.bash 
echo $magenta hello
\033[0;35m hello

Well that doesn’t look right.

This is because the echo command needs to be told about escape sequences that might be in the stuff it is printing out. Add a -e to your echo.

echo -e $magenta hello
 hello

You should see hello printed in a color, if you have a Solarized terminal it should be magenta.

Let’s add another color. How about red.

Open your solarized.bash back up and add the following.

red='\033[0;31m'

⚠️ Don’t forget to save, close, and source the file again to use your changes.

Let’s try both colors.

echo -e $magenta hello $red there
 hello  there

You may have noticed a slight problem here. The colors are working but the spaces are a bit off. That’s because we are including spaces between everything, even if the color codes are invisible and take up no spaces at all. To get rid of the extra space we need to put the colors right next to the words.

echo -e $magentahello $redthere

Doh! Notice that doing that stops everything from working. That’s because Bash is looking for something in $magnetahello instead of $magenta and then hello.

Thankfully Bash has a way to separate the name from the text that follows using curly brackets.

echo -e ${magenta}hello ${red}there
hello there

Much better.

We still have a lot of other Solarized colors to add. But let’s pause to see how we might use them best.

The way we are using them now we always have to use echo -e to get them to show up. But there may be places we would want to use them that do not allow for that. For example, let’s read in a name to greet using the read command.

Type in the following on the shell and then a name when it waits.

read name

Now do the following to print the $name.

echo -e ${magenta}hello ${red}$name

That’s all well and good until we want to prompt the user with some text using the read -p. (Even though we could just use echo or printf this helps demonstrate the problem with echo -e.)

read -p "What's your name? " name

Run that to see the difference.

Now comes the problem I talked about earlier. How do we change the color of the prompt? We can’t put a read -ep because that is not supported.

Here is $() (dollar-parens) come to the rescue.

read -p "$(echo -ne $magenta)What's your name? " name

What if we made a small function that echoed all the colors?

Let’s start with just one.

First we need to creation a Bash function. We’ll use the method that requires the least amount of typing. This won’t run yet, but be patient.

# source me (don't execute me)

sol () {

}

Now let’s start with a default color, say magenta.

# source me (don't execute me)

sol () {
  echo -ne '\033[0;35m'
}

That actually gives us something we can use.

Save your file and run the following from the command line.

source solarized.bash
echo $(sol) something colorful 
something colorful

It should be magenta.

Ok, that is a lot of work just for one color, but we have laid the foundation for making all the colors work. Let’s add them now.

To do this let’s start with an argument m to be the first parameter.

Parameters in bash are variables that are numbers. For example $1, $2, etc.

We also need an if statement. We will use the ever powerful Bash version with [[ and ]]. Keep in mind that these are actually commands and have to be treated as such by having spaces in front of them, for example.

We will the simple = operator for comparing. This is a rare case in programming when a single = actually means is equal to (instead of is assigned).

If also required a then as well as a fi to close it off.

# source me (don't execute me)

sol () {
  if [[ $1 = m ]]; then
    echo -ne '\033[0;35m'
  fi
}

Let’s try this one. Don’t forget the m.

source solarized.bash
echo $(sol m) something colorful 
something colorful

Finally we can add more colors. This is where elif comes in.

sol () {
  if [[ $1 = m ]]; then
    echo -ne '\033[0;35m'
  elif [[ $1 = r ]]; then
    echo -ne '\033[0;31m'
  fi
}

Now we have red. Let’s try it.

source solarized.bash
echo $(sol m)something $(sol r)red 
something red

There’s lots of other colors and this if stuff is getting pretty verbose. There’s actually a better way handle a lot of if statements together. It’s called the case statement. You may know it from other languages as the switch statement. Here’s the exact same if code done with case instead.

sol () {
  case $1 in
    m) echo -ne '\033[0;35m' ;;
    r) echo -ne '\033[0;31m' ;;
  esac
}

We could further simplify this with a local variable. Often the keyword local is used in Bash but you can just as well use declare and be consist since declare is used for other types of local variables (namely arrays).

sol () {
  declare esc
  case $1 in
    m) esc='\033[0;35m' ;;
    r) esc='\033[0;31m' ;;
  esac
  echo -ne $esc
}

That’s it. The rest is the boring part. You just need to put in all the escapes for the different colors.

sol () { 
  declare esc
  case $1 in 
    b03) esc='\033[1;30m' ;;
    b02) esc='\033[0;30m' ;;
    b01) esc='\033[1;32m' ;;
    b00) esc='\033[1;33m' ;;
    b0)  esc='\033[1;34m' ;;
    b1)  esc='\033[1;36m' ;;
    b2)  esc='\033[0;37m' ;;
    b3)  esc='\033[1;37m' ;;
    y)   esc='\033[0;33m' ;;
    o)   esc='\033[1;31m' ;;
    r)   esc='\033[0;31m' ;;
    m)   esc='\033[0;35m' ;;
    v)   esc='\033[1;35m' ;;
    b)   esc='\033[0;34m' ;;
    c)   esc='\033[0;36m' ;;
    g)   esc='\033[0;32m' ;;
    esac
}

But wait, what if there was an escape code to clear the screen, the line, or some way to create a random color. Well, of course, there is.

TODO Stay Tuned.