Dennis Williamson wrote: > Linda Walsh wrote: > > GLOBAL="hi there" > > {foo=GLOBAL echo ${!foo}; }
Note that this tickles a problem since foo isn't set before $foo is expanded. Use this following with a semicolon instead: GLOBAL="hi there" {foo=$GLOBAL; echo ${!foo}; } > You had a missing dollar sign. > > I'm assuming you meant: > > GLOBAL="hi there" > {foo=$GLOBAL echo ${!foo}; } Er.. No. There is a missing semicolon as described above and in other messages in the thread but the dollar size is intended to be excluded so that foo contains the string "GLOBAL" and ${!foo} will indirect through it. The magic is the ${!parameter} syntax. If you look at the bash documentation for ${parameter} you will find the following documentation. The second paragraph explains the '!' part and is the part needed to understand the indirection. ${parameter} The value of parameter is substituted. The braces are required when parameter is a positional parameter with more than one digit, or when parameter is followed by a character which is not to be interpreted as part of its name. 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. The exceptions to this are the expansions of ${!prefix*} and ${!name[@]} described below. The exclamation point must immediately follow the left brace in order to introduce indirection. And so as you can see from this ${!foo} expands the value of foo to be the string "GLOBAL" and then continues using that as an indirection and expands the value of $GLOBAL. With echo ${!foo} it would be very similar to saying 'eval echo \$$foo'. It would dynamically indirect through and pick up the value of GLOBAL. You can tell the difference by changing the value of GLOBAL between echo statements. Static direct binding: #!/bin/bash GLOBAL="one" foo=$GLOBAL { echo ${foo}; } GLOBAL="two" ( echo ${foo} ) Emits: one one Dynamic indirect binding: #!/bin/bash GLOBAL="one" foo=GLOBAL { echo ${!foo}; } GLOBAL="two" ( echo ${!foo} ) Emits: one two And the difference between using {...} and (...) is back to the original discussion of the thread that subshells have access to copies of all parent variables including variables that were not explicitly exported. Hope that helps to clarify things. Bob