Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I'm reading "Bash Guide for Beginners". It says:

If the first character of PARAMETER is an exclamation point, 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 example given is:

franky ~> echo ${!N*} NNTPPORT NNTPSERVER NPX_PLUGIN_PATH 

I don't quite understand here:

the value of the variable formed from the rest of PARAMETER

As the PARAMETER is just !N*, then

the rest of PARAMETER

is just N*. How could this form a variable? Did Bash search all possible command there?

like image 726
athos Avatar asked Dec 15 '11 05:12

athos


People also ask

What does ${ var mean?

In the bash shell, ${! var} is a variable indirection. It expands to the value of the variable whose name is kept in $var . The variable expansion ${var+value} is a POSIX expansion that expands to value if the variable var is set (no matter if its value is empty or not).

What does VAR mean in bash?

As you see, it is a way to define "variable variables". That is, to use variables whose content is the name of another variable. From Bash Reference Manual → 3.5.

What is the expansion of VAR?

The roots of Value-at-Risk (VaR) can be traced backed to 1920's when was initially used by the NYSE as a risk measure to impose capital requirements on its members.

What is an expansion parameter?

Parameter expansion can be used to modify, expand or replace the value of the parameter. The optional braces are used with the variable when using variable parameter expansion, such as 'echo ${myvar}'.


2 Answers

If you read the bash man page, it basically confirms what you have stated:

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.

However, reading on from there:

The exceptions to this are the expansions of ${!prefix*} and ${!name[@]} described below.

${!prefix*} Names matching prefix. Expands to the names of variables whose names begin with prefix, separated by the first character of the IFS special variable.

In other words, your particular example ${!N*} is an exception to the rule you quoted. It does, however, work as advertised in the expected cases, such as:

$ export xyzzy=plugh ; export plugh=cave  $ echo ${xyzzy}  # normal, xyzzy to plugh plugh  $ echo ${!xyzzy} # indirection, xyzzy to plugh to cave cave 
like image 167
paxdiablo Avatar answered Oct 09 '22 13:10

paxdiablo


There appears to be an exception when the given "indirection" ends in a *, as it does here. In this case, it gives all variable names that start with the part you specified (N here). Bash can do that because it tracks variables and knows which ones exist.

True indirection is this:
Say I have a variable $VARIABLE set to 42, and I have another variable $NAME set to VARIABLE. ${!NAME} will give me 42. You use the value of one variable to tell you the name of another:

$ NAME="VARIABLE" $ VARIABLE=42 $ echo ${!NAME} 42 
like image 33
Kevin Avatar answered Oct 09 '22 13:10

Kevin