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
Your first result shows the problem:
The variable Green contains an string of
a backlash, a zero, a 3, etc.
.It was set by:
Green="\033[0;32m"
. As such it is not a color code.The text inside the variable needs to be interpreted (using echo -e, printf or $'...').
Let me explain with code:
What you mean to do is:
In great color green. This could print the color but will not be useful for PS1:
As it means that the string has to be interpreted by
echo -e
before it works.An easier way (in bash) is :
Please note the
` $'...' `
Having solved the issue of the variable
Green
, accesing it indirectly by the value of var colorstr is a second problem that could be solved by either:Note Please do not work with un-quoted values (as I did here because the values were under my control) in general. Learn to quote correctly, like:
And with that, you could write an PS1 equivalent to:
with:
Using eval should do it:
The last test is in color green.
You will want to write an alias to a function. Check out http://tldp.org/LDP/abs/html/functions.html, decent little tutorial and some examples.
EDIT: Sorry, looks like I misunderstood the issue. First it looks like your using the variables wrong, check out http://www.thegeekstuff.com/2010/07/bash-string-manipulation/. Also, what is invoking this script? Are you adding this to the .bash_profile or is this a script your users can launch? Using export should make the changes take effect right away without needed relog.
Bash supports associative arrays. Don't use indirection when you could use a dict. If you don't have associative arrays, upgrade to bash 4, ksh93, or zsh. Apparently mksh is adding them eventually as well, so there should be plenty of choice.
Though we're using
eval
, it's a different type of indirection for a different reason. Note how all the necessary guarantees are made for making this safe.See also: http://mywiki.wooledge.org/BashFAQ/006
Using
eval
is the classic solution, butbash
has a better (more easily controlled, less blunderbuss-like) solution:${!colour}
The Bash (4.1) reference manual says:
For example:
(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 plainecho
didn't show anything and I needed to see what was being echoed, I used an old friend I wrote about 24 years ago.)