Lookup shell variables by name, indirectly [duplicate]

坚强是说给别人听的谎言 提交于 2019-11-26 02:23:58

问题


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!


回答1:


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.




回答2:


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.


Note: 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.


回答3:


${!varname} should do the trick

$ var="content"
$ myvar=var
$ echo ${!myvar}
content



回答4:


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}



回答5:


# bmuSetIndirectVar()
# TO DOUBLE CHECK THIS COMMENT AND DEMO
# This function is an helper to read indirect variables.
# i.e. get the content of a variable whose name is saved
# within an other variable. Like:
# MYDIR="/tmp"
# WHICHDIR="MYDIR"
#       bmuSetIndirectVar "WHICHDIR" "$MYDIR"
#
bmuSetIndirectVar(){
    tmpVarName=$1
    locVarName=$1
    extVarName=$2
    #echo "debug Ind Input >$1< >$2<"
    eval tmpVarName=\$$extVarName
    #echo "debug Ind Output >$tmpVarName< >$extVarName<"
    export $locVarName="${tmpVarName}"
}

I am currently using this little function. I am not fully happy with it, and I have seen different solutions on the web (if I could recall I would write them here), but it seems to work. Within these few lines there is already some redundancy and extra data but it was helpful for debugging.

If you want to see it in place, i.e. where I am using it, check: https://github.com/mariotti/bmu/blob/master/bin/backmeup.shellfunctions.sh

Of course it is not the best solution, but made me going on with the work, in the hope I can replace it with something a bit more general soon.



来源:https://stackoverflow.com/questions/1694196/lookup-shell-variables-by-name-indirectly

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!