63

For example, I have a variable:

env_name="GOPATH"

Now I want to get the environment variable GOPATH as if like this:

echo $GOPATH

How can I get $GOPATH by $env_name?

Gilles 'SO- stop being evil'
  • 807,993
  • 194
  • 1,674
  • 2,175
roger
  • 769
  • 1
  • 5
  • 4
  • 9
    `printenv $env_name` –  Dec 28 '15 at 10:30
  • Or http://unix.stackexchange.com/questions/222487/bash-dynamic-variable-variable-names?lq=1 – muru Dec 28 '15 at 20:13
  • See here for most awesome answer by awesome dude -> http://unix.stackexchange.com/questions/229849/indirectly-expand-variables-in-shell – Nick Grealy Feb 14 '17 at 05:54
  • in this case, `printenv GOPATH` meaning you can alias such as `alias p='printenv'` and then it's just `p GOPATH`. Get any environment variable by just typing `p` instead of the more clumsy `echo $...` – BBW Before Windows Dec 12 '17 at 23:17

2 Answers2

68

Different shells have different syntax for achieving this.

In bash, you use variable indirection:

printf '%s\n' "${!env_name}"

In ksh, you use nameref aka typeset -n:

nameref env_name=GOPATH
printf '%s\n' "$env_name"

In zsh, you use P parameter expansion flag:

print -rl -- ${(P)env_name}

In other shell, you must use eval, which put you under many security implications if you're not sure the variable content is safe:

eval "echo \"\$$name_ref\""
cuonglm
  • 150,973
  • 38
  • 327
  • 406
0

You can avoid eval if you let a shell's prompt expansion handle the indirection:

PS1=\$$env_name sh -si </dev/null 2>&1

This has some advantages - particularly in that the expansion is not followed by command execution. And so the only hazard here is if $env_name contains a command substitution. The variable which it expands to can contain anything which might look like a command substitution without danger because the expansion isn't attempted three times - only twice. In this way validation is fairly easy:

PS1=$"${env_name##*[\'\(]*}" sh -si </dev/null 2>&1

Given a POSIX sh, that should be plenty safe without any risk of arbitrary code execution, while still printing any exported environment variables (of the kind a shell can understand) to standard-out.

mikeserv
  • 57,448
  • 9
  • 113
  • 229