user3184897
user3184897

Reputation:

echo printing -e in bash

I've gotten this script I've created in Bash, and one of the functions I'm using is echo and I'm using the -e flag for interpretations of \ backslash escapes. I have a script that prints text in color, but when it's echoing out the message that's gonna be in color it also prints the -e flag with the message

case in example here;

NC='\033[31;0m\'       # no colors or formatting
RED='\033[0;31;1m\'    # print text in bold red
PUR='\033[0;35;1m\'    # print text in bold purple
YEL='\033[0;33;1m\'    # print text in bold Yellow
GRA='\033[0;37;1m\'    # print text in bold Gray

echo -e "This ${YEL}Message${NC} has color\nwith ${RED}new${NC} lines.

Output:

-e This Message has color.
with new lines

and if I also happen to have another command to be run in the bash script I also get this even though it shouldn't. For example with running with screen at the start of running this in a script.

\033[31;0m\033[0;31;1mscreen: not found

EDIT**

To detail more with what I'm trying to do;

#!/bin/sh

##
## Nexus Miner script
##


NC='\033[31;0m'
RED='\033[0;31;1m'
PUR='\033[0;35;1m'
YEL='\033[0;33;1m'
GRA='\033[0;37;1m'

ADDR="<wallet-address-goes-here"
NAME="<worker-name-goes-here>"
URL="nexusminingpool.com"

## check if user is root, if true, then exit with status 1, else run program.
if [ `whoami` = root ]; then
   echo -e "\n${PUR}You don't need ROOT for this!${NC}\n" 1>&2
       exit 1;

## running Nexus Miner with Screen so you can run it in background
## and call it up at any time to check mining progress of Nexus CPU Miner.
   else
       echo -e "\n\n${YEL}Normal User?${NC} ${GRA}[OK]${NC}\n${GRA}Session running with${NC} ${RED}SCREEN${NC}${GRA}, Press${NC} ${RED}^C + A${NC} ${GRA}then${NC} ${RED}^C + D${NC} ${GRA}to run in background.${NC}\n${GRA}to resume enter `${NC}${RED}screen -r${NC}${GRA}` from Terminal.${NC}\n\n"
       echo -e "${PUR}Nexus CPU Miner${NC}\n${GRA}Wallet Address:${NC} $ADDR\n${GRA}Worker Name:${NC} $NAME\n${GRA}CPU Threads:${NC} (Default: 2)\n\n"

       ## call strings for wallet address and worker name varibles followe by thread numbers (default: 2)
       ## run nexus cpu miner within screen so it can run in the background
       `screen /home/user/PrimePoolMiner/nexus_cpuminer $URL 9549 $ADDR $NAME 2`
fi

Upvotes: 8

Views: 5222

Answers (3)

sandbox
sandbox

Reputation: 9

Following approach also fixes the problem with leading -e :

bash -c 'echo -e "This is a \x1b[31mred fragment\x1b[39m of text"'

... or with octal literal as you tried initially (which is exactly the same):

bash -c 'echo -e "This is a \033[31mred fragment\033[39m of text"'

The problem with leading -e could appear when you want echo from python (with os.popen('...').read() statement). The same effect in python code:

import os
cmd_echo = """bash -c 'echo -e "This is a \x1b[31mred fragment\x1b[39m of text"'"""
print(f"... > {cmd_echo}")
print(os.popen(cmd_echo).read())

In all described cases the output should be with red fragment colored with red. Sorry, no idea how to print it here :-(

Upvotes: 0

Maxim Egorushkin
Maxim Egorushkin

Reputation: 136238

Remove the trailing backslashes and add a closing quote:

NC='\033[31;0m'       # no colors or formatting
RED='\033[0;31;1m'    # print text in bold red
PUR='\033[0;35;1m'    # print text in bold purple
YEL='\033[0;33;1m'    # print text in bold Yellow
GRA='\033[0;37;1m'    # print text in bold Gray
echo -e "This ${YEL}Message${NC} has color\nwith ${RED}new${NC} lines."

And it works as expected in bash.

If you save this script into a file, run it like bash <file>.


Try type -a echo to see what it is. The first line of output should be echo is a shell builtin:

$ type -a echo
echo is a shell builtin
echo is /usr/bin/echo
echo is /bin/echo

Upvotes: 3

Keith Thompson
Keith Thompson

Reputation: 263237

You wrote, "I've gotten this script I've created in Bash", but you haven't told us exactly what you mean by that.

UPDATE : The question has been updated. The script's first line is #!/bin/sh. Read on for an explanation and solution.

I can reproduce the problem on my system by including your code in a script starting with

#!/bin/sh

I can correct the problem by changing that first line to

#!/bin/bash

/bin/sh on my system happens to be a symlink to dash. The dash shell has echo as a builtin command, but it doesn't support the -e option. The #! line, g othe

There are numerous implementations of the echo command: most shells provide it as a builtin command (with various features depending on the shell), and there's likely to be an external command /bin/echo with its own subtly different behavior.

If you want consistent behavior for printing anything other than a simple line of text, I suggest using the printf command. See https://unix.stackexchange.com/questions/65803/why-is-printf-better-than-echo (cited by Josh Lee in a comment).

The #! line, known as a shebang, controls what shell is used to execute your script. The interactive shell you execute the script from is irrelevant. (It pretty much has to be that way; otherwise scripts would behave differently for different users). In the absence of a #! line, a script will (probably) be executed with /bin/sh, but there's not much point in not being explicit.

Upvotes: 13

Related Questions