13

For some reason my shell script stopped printing my menu in color and is actually printing the literal color code instead. Did I somehow escape the color coding?

Script

#!/bin/bash 

function showEnvironments {
echo -e "\e[38;5;81m"
echo -e "      SELECT ENVIRONMENT       "
echo -e "[1] - QA"
echo -e "[2] - PROD"
echo -e "\e[0m"
}

showEnvironments

Output

\e[38;5;81m

SELECT ENVIRONMENT

[1] - Staging

[2] - QA

\e[0m

I am using iTerm on Mac OSX and the TERM environment variable is set to xterm-256color.

6
  • You should edit your question to include the terminal emulator that you're using and the contents of the TERM environment variable. Commented May 9, 2016 at 12:38
  • TERM=xterm-256color TERM_PROGRAM=iTerm.app Is that what you were looking for?
    – Adrian E
    Commented May 9, 2016 at 12:50
  • Yes. I've edited your question to include this important information. I don't use a Mac so I don't know how iTerm would need to be configured to interpret ANSI escape sequences correctly. Commented May 9, 2016 at 13:05
  • See Makefile Adding colors doesn't work on OS X Commented May 11, 2016 at 23:38
  • fwiw I ended up just outputting to a file: echo "$stuff" >> myscript.sh Commented Oct 10, 2021 at 17:33

4 Answers 4

21

There are several apparent bugs in the implementation of echo -e in bash 3.2.x, which is what ships with Mac OS X. The documentation claims that \E (not \e) represents ESC, but neither appears to work. You can use printf instead:

printf "\e[38;5;81mfoo\e[0m\n"

or use (as you discovered) \033 to represent ESC.

Later versions of bash (definitely 4.3, possible earlier 4.x releases as well) fix this and allow either \e or \E to be used.

3
  • I wonder how this is handled with zsh? Commented Oct 10, 2021 at 17:34
  • 1
    Works fine in zsh, at least in 5.7.1. I don't know if there was ever a similar bug in older versions of zsh (I see no reason to think there would be just because bash had one.)
    – chepner
    Commented Oct 11, 2021 at 12:50
  • It's less of an issue in zsh (unless you are trying to use it as a POSIX shell, for example as /bin/sh), because you can write things like print -P "%F{81}foo%f" in a terminal-independent way.
    – chepner
    Commented Oct 11, 2021 at 12:52
10

Two ways to do this: reference colors directly or assign to variable to reference them easier later in the script.

cNone='\033[00m'
cRed='\033[01;31m'
cGreen='\033[01;32m'
cYellow='\033[01;33m'
cPurple='\033[01;35m'
cCyan='\033[01;36m'
cWhite='\033[01;37m'
cBold='\033[1m'
cUnderline='\033[4m'

echo -e "\033[01;31m"
echo -e "hello"
echo -e "\033[00m"

echo -e "${cGreen}"
echo -e "hello"
echo -e "${cNone}"

I hope this helps.

4

I figured it out. It appears that the escape character I am using for the color code is not recognized in my terminal.

Based on http://misc.flogisoft.com/bash/tip_colors_and_formatting#colors1 valid escape codes are:

\e
\033
\x1B

When I changed my colors from \e[38;5;81m to \033[38;5;81m it started working as expected.

Thanks to everyone else for the suggestions and help!

0
1

Two potential things to try:

  • run stty sane to reset the terminal settings
  • check the $TERM environment variable

Not the answer you're looking for? Browse other questions tagged or ask your own question.