I'm trying to set up my PS1
prompt variable to dynamically choose a color. To do this, I've defined a bunch of local variables with color names:
$ echo $Green \033[0;32m
but I was hoping to use those in dynamically assigning variables, but I can't figure out how to expand them properly:
> colorstr="\${$color}" > echo $colorstr ${Green}
I've tried a dozen combinations of eval
, echo
, and double-quotes, and none seem to work. The logical way (I thought) to expand the variable results in an error:
> colorstr="${$color}" -bash: ${$color}: bad substitution
(for clarity I've used >
instead of $
for the prompt character, but I am using bash)
How can I expand that variable? i.e., somehow get the word "Green" to the value \033[0;32m
? And prefereably, have bash or the terminal parse that \033[0;32m
as the color green too.
EDIT: I was mis-using ${!x}
and eval echo $x
previously, so I've accepted those as solutions. For the (perhaps morbidly) curious, the functions and PS1
variable are on this gist: https://gist.github.com/4383597
Parameter expansion comes in many forms in bash, the simplest is just a dollar sign followed by a name, eg $a. This form merely substitutes the value of the variable in place of the parameter expansion expression. The variable name can also optionally be surround by braces, eg ${a}.
Just use double quotes instead of single quotes. You'll also need to use {} to delimit the number_line variable correctly and escape the \ , too.
$() means: "first evaluate this, and then evaluate the rest of the line". Ex : echo $(pwd)/myFile.txt. will be interpreted as echo /my/path/myFile.txt. On the other hand ${} expands a variable. Ex: MY_VAR=toto echo ${MY_VAR}/myFile.txt.
Using eval
is the classic solution, but bash
has a better (more easily controlled, less blunderbuss-like) solution:
${!colour}
The Bash (4.1) reference manual says:
If the first character of parameter is an exclamation point (!), a level of variable indirection is introduced. Bash uses the value of the variable formed from the rest of parameter as the name of the variable; this variable is then expanded and that value is used in the rest of the substitution, rather than the value of parameter itself. This is known as indirect expansion.
For example:
$ Green=$'\033[32;m' $ echo "$Green" | odx 0x0000: 1B 5B 33 32 3B 6D 0A .[32;m. 0x0007: $ colour=Green $ echo $colour Green $ echo ${!colour} | odx 0x0000: 1B 5B 33 32 3B 6D 0A .[32;m. 0x0007: $
(The odx
command is very non-standard but simply dumps its data in a hex format with printable characters shown on the right. Since the plain echo
didn't show anything and I needed to see what was being echoed, I used an old friend I wrote about 24 years ago.)
Using eval should do it:
green="\033[0;32m" colorstr="green" eval echo -e "\$$colorstr" test # -e = enable backslash escapes test
The last test is in color green.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With