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?
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It only takes a minute to sign up.
Sign up to join this communityI'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?
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}."
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"
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
.
Oct 20, 2017 at 10:48
autoload -U colors
colors
echo $fg[green]YES$fg[default] or $fg[red]NO$fg[default]?
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"
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" }'
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.
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
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)"
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