LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   variable expansion in bash (https://www.linuxquestions.org/questions/programming-9/variable-expansion-in-bash-611631/)

coolhandluke1 01-06-2008 11:32 PM

variable expansion in bash
 
Im reading a book on shell scripting and an example is given:

***FULL EXAMPLE***
# $envvar = PATH
dirpath=$(eval echo '${'"$envvar"'}' 2>/dev/null | tr : ' ')


***SPECIFIC PART I DONT UNDERSTAND***
# $envvar = PATH
echo '${'"$envvar"'}'

this prints:
${PATH}


What i am needing help understanding is:

how does the argument string '${'"$envvar"'}' get converted to ${PATH}? I know it has something to do with evaluation order of the shell, however the books explanation of this subject is not detailed enough for me.

Thanks in advance

Hko 01-07-2008 03:21 AM

Quote:

Originally Posted by coolhandluke1 (Post 3013929)
how does the argument string '${'"$envvar"'}' get converted to ${PATH}? I know it has something to do with evaluation order of the shell, however the books explanation of this subject is not detailed enough for me.

The shell variable envvar has the value 'PATH'. So $envvar is substituted ("expanded" in shell lingo) with PATH.

'${' and '}' are just a literal strings. The single quotes prevent the shell from treating the $ and the { as special character and trying to interpret them.

The double quotes prevents whitespace to be interpreted as seperators. And since PATH does not contain spaces, the double quotes are not really needed in this case. So this would also do it:
Code:

dirpath=$(eval echo '${'$envvar'}' 2>/dev/null | tr : ' ')
BTW, $PATH does the same as ${PATH}. Only in some cases the curly brackets are needed. Not here. So this command would do the same (in this case):
Code:

dirpath=$(eval echo '$'$envvar 2>/dev/null | tr : ' ')
So a string ${PATH} is created by expanding the envvar variable and we want that string expanded yet another time by the shell. This is done by the eval command. This is some sort of trick to get the value of a variable, while the name of the variable itself is inside a variable. The bash shell has a special construction to do this. So if the shell is bash, this does the same as you original full example:
Code:

dirpath=$(echo ${!envvar} | tr : ' ')

gnashley 01-07-2008 03:27 AM

Looks like a slight typo to me. Try it like this:

Code:

#!/bin/bash
# save me as 'tryit.sh'
envvar=PATH
dirpath=$(eval echo '${'"$envvar"'}' 2>/dev/null | tr : ' ')
echo $dirpath

Then run it:
sh ./tryit.sh
/usr/local/bin /usr/bin /bin /usr/X11R6/bin /usr/games /usr/lib/java/bin /usr/lib/java/jre/bin /usr/lib/qt/bin .

You should use the CODE tags when posting code so we can read it accurately.

coolhandluke1 01-07-2008 05:35 AM

Quote:

Originally Posted by Hko (Post 3014095)
The shell variable envvar has the value 'PATH'. So $envvar is substituted ("expanded" in shell lingo) with PATH.

'${' and '}' are just a literal strings. The single quotes prevent the shell from treating the $ and the { as special character and trying to interpret them.

Thank you for your initial reply. This answers my question right here.

archtoad6 01-09-2008 03:45 PM

The whole sequence prints the contents of the Environment Variable "PATH" w/ the colons changed to spaces. For some reason, it's using indirection (the value of the variable envvar, is the name of the variable PATH; & so the indirect value of envvar is the value of PATH). Why the author did not just use straight bash indirect expansion, I don't know. The following produces the same result:
Code:

envvar=PATH
dirpath=`echo ${!envvar} 2>/dev/null |tr : \ `



All times are GMT -5. The time now is 09:34 AM.