Ora

How to Color Shell Output?

Published in Shell Output Coloring 5 mins read

Coloring shell output is achieved by using ANSI escape sequences, which are special character sequences that terminals interpret as commands to change formatting, such as text color, background color, and text style. These sequences enable scripts and commands to produce aesthetically enhanced and more readable terminal output.

Understanding ANSI Escape Codes

A script can use escape sequences to produce colored text on the terminal. The fundamental escape sequence for changing text attributes begins with \033[ (or \e[) and ends with m. Between these, you place one or more semicolon-separated Select Graphic Rendition (SGR) parameters, which are numerical codes that specify the desired formatting.

Common SGR Parameters

Colors for text are represented by specific color codes. Here are the standard foreground (text) color codes:

Code Color Name Description
0 Reset Resets all attributes to default
30 Black Text color: Black
31 Red Text color: Red
32 Green Text color: Green
33 Yellow Text color: Yellow
34 Blue Text color: Blue
35 Magenta Text color: Magenta
36 Cyan Text color: Cyan
37 White Text color: White

Beyond these basic foreground colors, you can also specify background colors (codes 40-47), bright versions of colors (codes 90-97 for foreground, 100-107 for background), and text attributes like bold, underline, or italic.

Practical Examples of Coloring Shell Output

The most common way to print colored text in a shell like Bash or Zsh is using the echo command with the -e option, which enables the interpretation of backslash escapes.

1. Basic Text Colors

To color a simple piece of text, you combine the escape sequence, the color code, your text, and finally the reset code to prevent subsequent output from being colored.

echo -e "\033[31mThis text is red.\033[0m"
echo -e "\033[32mThis text is green.\033[0m"
echo -e "\033[34mThis text is blue.\033[0m"
  • \033[31m: Sets the foreground color to red.
  • \033[32m: Sets the foreground color to green.
  • \033[34m: Sets the foreground color to blue.
  • \033[0m: Resets all formatting (color, style) to the default. This is crucial for consistent output.

2. Using Background Colors

To change the background color, you use codes 40-47. You can combine foreground and background colors by separating their codes with a semicolon.

echo -e "\033[40m\033[37mWhite text on a black background.\033[0m"
echo -e "\033[41m\033[33mYellow text on a red background.\033[0m"
echo -e "\033[42;30mBlack text on a green background.\033[0m" # Multiple codes with semicolon
  • \033[40m: Sets the background color to black.
  • \033[41m: Sets the background color to red.
  • \033[42;30m: Sets background to green and foreground to black.

3. Adding Text Styles

You can also apply styles like bold, italic, or underline using additional SGR parameters.

Code Style
1 Bold/Bright
3 Italic
4 Underline
echo -e "\033[1mThis text is bold.\033[0m"
echo -e "\033[3mThis text is italic.\033[0m"
echo -e "\033[4mThis text is underlined.\033[0m"
echo -e "\033[1;31mBold Red Text.\033[0m" # Bold and red

4. Defining Color Variables for Reusability

For complex scripts, it's good practice to define color codes as variables to make your code cleaner and easier to manage.

RED='\033[31m'
GREEN='\033[32m'
YELLOW='\033[33m'
BLUE='\033[34m'
NC='\033[0m' # No Color (Reset)

echo -e "${RED}Error: ${YELLOW}Something went wrong!${NC}"
echo -e "${GREEN}Success: ${BLUE}Operation completed.${NC}"

This approach helps maintain consistency and simplifies changes to your color scheme.

Advanced Coloring Techniques

While echo -e covers most basic needs, other methods and tools offer more advanced control.

1. Using tput for Terminal Capabilities

The tput command provides a more portable way to manage terminal capabilities, including colors, as it consults the termcap or terminfo database.

# Set foreground color to red
tput setaf 1
echo "This text is red using tput."
# Reset colors
tput sgr0
echo "This text is default color."

# Combine with background
tput setab 2 # Green background
tput setaf 0 # Black foreground
echo "Black on green using tput."
tput sgr0
  • tput setaf [0-7]: Sets the foreground color (0=black, 1=red, 2=green, etc.).
  • tput setab [0-7]: Sets the background color.
  • tput sgr0: Resets all attributes.

2. Customizing Shell Prompts

Your shell prompt (e.g., Bash's PS1 variable) can also be colored using ANSI escape codes to make it more informative or visually appealing.

# Example Bash PS1 with colors
export PS1="\[\e[32m\]\u@\h\[\e[0m\]:\[\e[34m\]\w\[\e[0m\]\$ "
  • \[...\]: These brackets tell Bash to ignore the enclosed escape sequences when calculating prompt length, preventing issues with line wrapping.
  • \u@\h: Username and hostname.
  • \w: Current working directory.
  • \$: Standard prompt character ($ for user, # for root).

3. Coloring Specific Command Output

Many commands, like grep, ls, and diff, have built-in options or environment variables to enable colored output.

  • grep: Use grep --color=auto or set an alias alias grep='grep --color=auto'.
  • ls: Use ls --color=auto or set an environment variable LS_COLORS. Most modern distributions enable this by default through an alias. You can customize LS_COLORS to define colors for different file types. For example, export LS_COLORS='di=01;34:ex=01;32:' would make directories blue and executables green.
  • diff: Many diff tools, like git diff, offer colored output by default or with specific flags.

Considerations for Coloring Output

  • Terminal Compatibility: Most modern terminals (like xterm, GNOME Terminal, Konsole, iTerm2) support ANSI escape codes. Legacy terminals or those configured incorrectly might display raw escape sequences.
  • Readability: Use colors judiciously. Too many colors can make output harder to read and overwhelming.
  • Accessibility: Consider users with color blindness. Avoid relying solely on color to convey critical information.
  • Redirection: When redirecting output to a file, you typically don't want the escape sequences. Many commands (like grep --color=auto) automatically disable colors when output is not a terminal. If you use custom scripts, you might need to check if the output is a TTY before printing colors.

By understanding and utilizing ANSI escape sequences, you can significantly enhance the clarity and impact of your shell output, making your command-line experience more informative and visually engaging.