tags:

views:

87

answers:

4

Let's say I have a variable's name stored in another variable:

myvar=123
varname=myvar

now, I'd like to get 123 by just using $varname variable. Is there a direct way for that? I found no such bash builtin for lookup by name, so came up with this:

function var { v="\$$1"; eval "echo "$v; }

so

var $varname  # gives 123

Which doesn't look too bad in the end, but I'm wondering if I missed something more obvious. Thanks in advance!

+7  A: 

From the man page of bash:

${!varname}

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.

tangens
This syntax is a bash extension to the posix shell syntax. Don't use it except for your own local scripts.
DigitalRoss
Of course, that's it.Tried to RTFM, but somehow this description:----------------- ${!prefix*} ${!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. When @ is used and the expansion appears within double quotes, each variable name expands to a separate word.-----------------didn't strike me as the obvious answer.Cheers for that!
inger
@DigitalRoss: The question was is tagged with "bash", so why do you want to restrict the answer to posix standard?
tangens
It's a fine answer, and yes it does apply to bash. I guess the perfect answer would announce `${!varname}` and then note the portability issue to keep the OP out of possible trouble.
DigitalRoss
agreed, your answers together makes a perfect answer:)
inger
@inger: `${!prefix*}` and `${!prefix@}` are different from `${!prefix}`
Dennis Williamson
+3  A: 

There isn't a direct Posix-conforming syntax, only a bashism. I usually do this:

eval t=\$$varname

This will work on any Posix shell, including those systems where bash is the login shell and /bin/sh is something smaller and faster like ash. I like bash and use it for my login shell but I avoid bashisms in command files. One problem with writing bash-specific scripts is that even if you can count on bash being installed, it could be anywhere on the path. It might be a good idea in that case to use the fully general /usr/bin/env shebang style, but note that this is still not 100% portable and has security issues.

DigitalRoss
Depending on the context in which you need the value, you might use `$(eval \$$varname)` rather than an assignment.
Jonathan Leffler
Tried almost that, but missed it. Shorter than mine- cheers for that!
inger
+1  A: 

${!varname} should do the trick

$ var="content"
$ myvar=var
$ echo ${!myvar}
content
Arkaitz Jimenez
Thanks, seems your answer arrived just a moment later than tangens, so I selected that one:)
inger
+1  A: 

I usually look at Advance Bash-Scripting Guide when I need to freshen up my Bash skills.

Regarding your question look at Indirect References

Notation is:

Version < 2
\$$var

Version >= 2
${!varname}
Peter Lindqvist
Hmm, glanced that guide quickly - apparently too quickly:)Seem like I have to read through it properly.. thanks for the tip!
inger
It's my quick reference of choice, i tend to use it more frequently than the man pages. But as you say, a quick glance is sometimes not enough.
Peter Lindqvist