4

I'm trying to create function that will print message bound to variable in certain color. The message variable is passed as argument of this function. The problem is that I'm getting only text up to first space (only first word of message). My script looks like this:

#!/usr/bash

lbGREEN='\e[1;92m'
NC='\e[0m'

normalMessage="Everything fine"

echo_message() {

    echo -e  ${lbGREEN}$1${NC}

}

echo_message $normalMessage 

My output is:

Everything
that other guy
  • 116,971
  • 11
  • 170
  • 194
s-kaczmarek
  • 161
  • 1
  • 13

4 Answers4

5

As Inian pointed out in comments, your problem is unquoted variable expansion

echo_message $normalMessage 

becomes

echo_message Everything fine

once the variable expands, meaning that each word of your input string is getting read in as a separate argument. When this happens $1=Everything and $2=fine.

This is fixed by double-quoting your variable, which allows expansion, but will mean the result of the expansion will still be read as one argument.

echo_message "$normalMessage"

becomes

echo_message "Everything fine"

Like this $1=Everything fine

In the future, I recommend using https://www.shellcheck.net/, or the CLI version of shellcheck, it will highlight all kinds of common bash gotcha's, included unquoted expansion.

Will Barnwell
  • 4,049
  • 21
  • 34
4

For me, I had to change the header for "#!/bin/bash", but apparently that is not the problem for you.

In your echo you are printing only the first word with the $1, if you change it to $2 you will print the second word (parameter) and so on.

You can pass the name inside quotes or print all the parameters with $@

Solution 1 (with $@):

lbGREEN='\e[1;92m'
NC='\e[0m'
normalMessage="Everything fine"
echo_message() {
    echo -e  ${lbGREEN}$@${NC}
}
echo_message $normalMessage

Solution 2 (with quotes):

lbGREEN='\e[1;92m'
NC='\e[0m'
normalMessage="Everything fine"
echo_message() {
    echo -e  ${lbGREEN}$1${NC}
}
echo_message "$normalMessage"
res
  • 775
  • 8
  • 16
1

You should get a look to https://stackoverflow.com/a/6212408/1428602

IMHO, $1 only return the 1st word, so you have to use a loop or try with $*

1

You've got the quoting wrong.

If you want to simulate the behaviour of echo, your function should accept multiple parameters, and print them all. Currently it's only evaluating the first parameter, so I suggest using $* instead. You also need to enclose the argument in double quotes to protect any special characters:

echo_message() {
    echo -e  "${lbGREEN}$*${NC}"
}

The special variable $* expands to all the arguments, separated by spaces (or more accurately, the first character of $IFS, which is usually a space character). Note that you almost always want "$@" instead of "$*", and this is one of the rare occasions where the latter is also correct, though with slightly different semantics if IFS is set to a non-standard value.

Now the function supports multiple arguments, and prints them all in green, separated by spaces. However, I would recommend that you also quote the argument when calling the function:

echo_message "$normalMessage"

While spaces in $normalMessage will now be treated correctly, other special characters like ! will still require the quotes.

Sven Marnach
  • 574,206
  • 118
  • 941
  • 841