Colorful Output in Shell Scripts

Make your outputs more readable using colors.


Shell scripts are invaluable for automating tasks on Unix-like systems. However, their outputs are often plain and can be hard to read, especially when displaying large amounts of information or highlighting errors and statuses. By adding some colorful output, you can make your scripts more user-friendly and visually appealing. In this article, we'll walk through how to achieve vibrant terminal outputs in your shell scripts, using ANSI escape sequences.

Why Use Color?

Colors help you:

  • Highlight errors and warnings
  • Differentiate statuses (success, failure, in-progress)
  • Emphasize important information
  • Improve the general readability of your script's output

Basics of ANSI Escape Codes

Terminal emulators typically support ANSI escape codes to control things like cursor movement, formatting, and colors.

Structure

An ANSI escape code starts with \033[ (or \e[ or \x1b[) and is followed by formatting codes, ending with m. For example:

\033[COLOR_CODEmYour Text\033[0m

Here, \033 represents the ESC character, COLOR_CODE specifies the color or style, and \033[0m resets the formatting.

Common Foreground Color Codes

Color Code
Black 30
Red 31
Green 32
Yellow 33
Blue 34
Magenta 35
Cyan 36
White 37
Reset 0

To make text bold, prefix the code with 1;, e.g., \033[1;31m.

Practical Examples

Let's explore how to add color to your shell script outputs.

1. Simple Color Output

#!/bin/bash

echo -e "\033[31mThis is red text\033[0m"
echo -e "\033[32mThis is green text\033[0m"
echo -e "\033[1;33mThis is bold yellow text\033[0m"

The -e flag enables interpretation of escaped characters.

2. Defining Color Variables

To avoid repetition and improve readability, define color variables at the top of your script:

# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color (reset)

echo -e "${RED}Error: Something failed!${NC}"
echo -e "${GREEN}Success: Task completed successfully.${NC}"
echo -e "${YELLOW}Warning: Disk space low.${NC}"

3. Function for Easy Coloring

Encapsulate coloring in a function for cleaner code:

color_echo() {
  COLOR=$1
  shift
  echo -e "${COLOR}$@${NC}"
}

color_echo $RED "Failed to install package."
color_echo $GREEN "Installation successful!"
color_echo $YELLOW "Proceed with caution."

4. Using Colors in Real-world Scripts

Here's a snippet that makes script output clearer when iterating over a directory:

#!/bin/bash

# Define colors
GREEN='\033[0;32m'
RED='\033[0;31m'
NC='\033[0m' # reset

for file in *; do
  if [ -f "$file" ]; then
    echo -e "${GREEN}File: $file${NC}"
  elif [ -d "$file" ]; then
    echo -e "${RED}Directory: $file${NC}"
  fi
done

5. Compatibility Considerations

Not all terminals support colors or ANSI codes. To make your script robust:

  • Check if tput is available and use it to get color codes:
if command -v tput >/dev/null; then
  RED=$(tput setaf 1)
  GREEN=$(tput setaf 2)
  YELLOW=$(tput setaf 3)
  NC=$(tput sgr0)
else
  RED='\033[0;31m'
  GREEN='\033[0;32m'
  YELLOW='\033[1;33m'
  NC='\033[0m'
fi
  • Optionally, provide a "color off" flag for users preferring plain output.
if [[ $NO_COLOR ]]; then
  RED=''
  GREEN=''
  YELLOW=''
  NC=''
fi

Advanced: 256 Colors and Beyond

Modern terminals support more colors using \033[38;5;Xm for foreground and \033[48;5;Xm for background, where X is a number from 0 to 255.

echo -e "\033[38;5;208mThis is orange text (color 208)\033[0m"

Conclusion

Adding color to your shell scripts can make them vastly more usable and informative. With just a few escape codes or helper functions, you can make crucial outputs pop, highlight issues, and craft a polished scripting experience.

Try it in your next project and see the difference!