30

I'm aware of libraries in languages such as Ruby and Javascript to make colorizing your terminal scripts easier by using color names like "red".

But is there something like this for shell scripts in Bash, or Ksh, or whatever?

1
  • 10
    please mark an answer as correct... you only marked 1 out of your total 46 asked questions so far!
    – m13r
    Commented Aug 8, 2014 at 11:04

7 Answers 7

49

You can define colours in your bash scripts like so:

red=$'\e[1;31m'
grn=$'\e[1;32m'
yel=$'\e[1;33m'
blu=$'\e[1;34m'
mag=$'\e[1;35m'
cyn=$'\e[1;36m'
end=$'\e[0m'

And then use them to print in your required colours:

printf "%s\n" "Text in ${red}red${end}, white and ${blu}blue${end}."
12

You can use tput OR printf

Using tput ,

just create function as below and use them

shw_grey () {
    echo $(tput bold)$(tput setaf 0) $@ $(tput sgr 0)
}

shw_norm () {
    echo $(tput bold)$(tput setaf 9) $@ $(tput sgr 0)
}

shw_info () {
    echo $(tput bold)$(tput setaf 4) $@ $(tput sgr 0)
}

shw_warn () {
    echo $(tput bold)$(tput setaf 2) $@ $(tput sgr 0)
}
shw_err ()  {
    echo $(tput bold)$(tput setaf 1) $@ $(tput sgr 0)
}

you can call above function using shw_err "WARNING:: Error bla bla"

Using printf

print red; echo -e "\e[31mfoo\e[m"
1
  • 4
    echo -e isn't printf, and also needs a warning that it differs from the tput option in that it doesn't automatically adapt to suit $TERM. Commented Oct 20, 2017 at 10:48
11

In zsh:

autoload -U colors
colors

echo $fg[green]YES$fg[default] or $fg[red]NO$fg[default]?
1
5

For simple common uses (full line of text in a single color only, with trailing newline) I modified jasonwryan's code as follows:

#!/bin/bash

red='\e[1;31m%s\e[0m\n'
green='\e[1;32m%s\e[0m\n'
yellow='\e[1;33m%s\e[0m\n'
blue='\e[1;34m%s\e[0m\n'
magenta='\e[1;35m%s\e[0m\n'
cyan='\e[1;36m%s\e[0m\n'

printf "$green"   "This is a test in green"
printf "$red"     "This is a test in red"
printf "$yellow"  "This is a test in yellow"
printf "$blue"    "This is a test in blue"
printf "$magenta" "This is a test in magenta"
printf "$cyan"    "This is a test in cyan"
1
  • Or in Awk, modified slightly: awk -v red="$(printf '\e[1;31m%%s\e[0m\\n')" -v green="$(printf '\e[1;32m%%s\e[0m\\n')" 'BEGIN { printf red, "This text is in red"; printf green, "This text is in green" }'
    – Wildcard
    Commented Oct 13, 2017 at 3:52
4

Better is to use tput which will handle escape characters depending on the output / terminal capabilities. (If a terminal cannot interpret \e[* color codes, then it will be "polluted" which makes output harder to read. (Or sometimes, if you grep such output, you will see those \e[* in the results)

See this tutorial for tput.

You can write :

blue=$( tput setaf 4 ) ;
normal=$( tput sgr0 ) ;
echo "hello ${blue}blue world${normal}" ;

Here is a tutorial to print a colored Clock in the terminal.

Also, note that tput may still prints escape character when redirecting STDOUT to a file:

$ myColoredScript.sh > output.log ;
# Problem: output.log will contain things like "^[(B^[[m"

To prevent this to happen, setup your tput variables like proposed in this solution.

0

Here is a POSIX-compliant shell function that I needed for a script:

#!/bin/sh

style() (
    offset=0
    for option in "$@"; do
        code=
        case $option in
            foreground|fg) offset=0 ;;
            background|bg) offset=10 ;;
            default|normal|off|reset) code=0 ;;
            bold) code=1 ;;
            underline) code=4 ;;
            black) code=30 ;;
            red) code=31 ;;
            green) code=32 ;;
            yellow) code=33 ;;
            blue) code=34 ;;
            magenta) code=35 ;;
            cyan) code=36 ;;
            white) code=37 ;;
            *) code=error ;;
        esac
        [ -z "$code" ] && continue
        [ "$code" = error ] && {
            printf %s\\n "unknown option: $option" >&2
            exit 1
        }
        [ "$code" -ge 30 ] && code="$((code+offset))"
        printf \\033\[%sm "$code"
    done
)

Valid options are bold and underline as well as 8 colors black, red, green, yellow, blue, magenta, cyan and white. Use off to disable all style options. To switch setting the color for foreground or background, prepend foreground (default) or background. (I.e. style foreground cyan background magenta has the same effect as style cyan background magenta.)

You can use it as follows with echo, printf or cat for example:

echo "Available text styles include $(style underline)underline$(style off) or $(style bold)bold$(style off)."
printf %s\\n "But also colors, for example $(style red)red$(style off) or $(style green)green$(style off) or $(style blue)blue$(style off)."
cat <<EOF
You can set the $(style black background yellow)background color$(style off) as well.
EOF

screenshot

set -- Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
colors="black red green yellow blue magenta cyan white"
for background in $colors; do
    printf %s "$(style background $background)"
    for foreground in $colors; do
        [ "$background" = "$foreground" ] && continue
        printf %s "$(style $foreground)$1 "
        shift
    done
done
printf %s\\n "$(style off)"

screenshot

0

I saw this elegant BASH oneliner (in Hacker News) that produces a list of HEX color codes in almost English words - useful mnemonics:

grep -P "^[ABCDEFabcdefOoIi]{6,6}$" /usr/share/dict/words | tr 'OoIi' '0011' | tr '[:lower:]' '[:upper:]' | awk '{print "#" $0}'

#ACAD1A
#B0BB1E
#DEBB1E
#AB1DED
#ACAC1A
#ACCEDE
#AC1D1C
#BAB1ED
#BA0BAB
#BEADED
#BEDDED
#BEEFED
#B0BBED
#B0D1CE
#B00BED
#CABBED
#CABB1E
#CADD1E
#C1CADA
#C0DDED
#C0FFEE
#C01FED
#DABBED
#DECADE
#DEC1DE
#DEC0DE
#DEEDED
#DEFACE
#DEF1ED
#DE1CED
#D0FFED
#D00DAD
#EDD1ED
#EFFACE
#FACADE
#F1BBED
#F0BBED
#0FF1CE
1
  • This is interesting, but off-topic. Commented Dec 19, 2022 at 17:37

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .