1

I am trying to write a function which will take 2 parameters. 1st a color name, 2nd text to be printed. I have also declared variables for colors as global variables. I want to expand the values by using 1st parameter string.

For now I am using switch case which is the worst way to do it I believe. Thank you in advance

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'

Print() {
    # I want to use 1st parameter to call the variables above
    # i.e. if red is passed, then i want value of red which is '\e[1;31m'
    printf $((${1}))
    printf "$2"
    printf $end
}

function call

Print red "string"

oguz ismail
  • 1
  • 16
  • 47
  • 69
Shivam Chauhan
  • 117
  • 1
  • 9
  • To the OP: Please ignore the downvotes on all 3 answers; the votes do not reflect the correctness of any of them. – chepner Mar 13 '20 at 19:28

3 Answers3

2

You are referring to indirect parameter expansion.

Print() {
    printf ${!1}
    printf "$2"
    printf $end
}

However, a safer way to write this is with

Print() {
  printf '%s%s%s' "${!1}" "$2" "$end"
}

This ensures you get the expected output even if one of the two arguments (the second in particular) contains a %.


Depending on how many other contexts use your color variables, I would move the escape handling into Print itself, so that you can simply define red=31, for example.

Print() {
  printf '\033[1;%sm%s\033[0m' "${!1}" "$2"
}
chepner
  • 497,756
  • 71
  • 530
  • 681
  • Hey @chepner thank you for the simplified version. But I checked what you said in first comment, I added "%" in the string and kept the Print function as it is. I didn't have any affect in the output. Maybe I didn't understand it correctly. Can you clarify? – Shivam Chauhan Mar 13 '20 at 21:13
  • 1
    As as simple example, try `foo="%s"; printf "$foo"`. You'll get no output, rather than the literal output `%s`. – chepner Mar 13 '20 at 22:21
1

You have to make bash interpret a string as a variable with ${!...}.

#!/bin/bash

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'

Print() {
    # I want to use 1st parameter to call the variables above
    # i.e. if red is passed, then i want value of red which is '\e[1;31m'
    echo -n ${!1}
    printf "$2"
    printf $end
}

Print "$@"

samthegolden
  • 1,366
  • 1
  • 10
  • 26
0

Try indirect expansion: What is indirect expansion? What does ${!var*} mean?

Here's your function with indirect expansion:

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'

Print() {
    # I want to use 1st parameter to call the variables above
    # i.e. if red is passed, then i want value of red which is '\e[1;31m'
    echo "${!1}$2$end"
}

Print red hello
Mark
  • 4,249
  • 1
  • 18
  • 27