64

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?

roger
  • 779
  • 10
    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

70

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
  • 153,898
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
  • 58,310