1

I want to reference a bash variable from a variable without using:

echo "${!VARNAME}"

Any ideas? Since I want to use the variable on fly and many such references are there, I can't declare them to another variable and use it.

Example:

var1=host
${var1}_file ----> host_file is another variable that i want to call in a command. 
  • 1
    What do you want to accomplish with this in the end? What kind of data do you have there? I'm sort of wondering if there wouldn't be a better way to do this. – ilkkachu Feb 18 '18 at 22:30
  • 1
    What is the reason not to use "${!VARNAME}" ? – user unknown Feb 18 '18 at 23:28
  • What we generally do is add concatenated variable and string to a variable and use that variable in "${!VARNAME}" . But i do not want to pass concatenated value to another variable but use it directly. something like ` ls host_file`. Like this i have to use multiple variables in a single command. – Rajesh Reddy B Feb 19 '18 at 9:19
  • @RajeshReddyB, yes, you explained in the question you want to generate variable names on the fly. I was trying to ask why. This has the smell of asking for X when you're actually trying to do Y. (See here and here) – ilkkachu Feb 19 '18 at 9:27
  • I'm actually trying to run execute below command. hadoop jar $DistcpJar -libjars $DistcpAclLibJar -Ddfs.encryption.key.provider.uri=${DestCluster}_${KmsUrl} -sourceconf $SourceConf -pugb -skipcrccheck -update hdfs://$(${SourceCluster}_NameService):${SourceCluster}_NameServicePort/$Source hdfs://${DestCluster}_NameService:${DestCluster}_NameServicePort/$DestLocation ------------------- where Source cluster is a positional parameter i pass to the main script and combining with another name forms a different variable. – Rajesh Reddy B Feb 19 '18 at 9:29
1

I can't really see why you would not want to use variable indirection unless you are writing a sh (not bash) script.

As has been mentioned, eval will work, but is generally frowned upon as its use has the potential to be dangerous, especially when evaluating user-supplied data without careful sanitation.

Another way of achieving the same effect is to use name-reference variables (available in bash since version 4.3).

var1=host

declare -n nameref="${var1}_file"

nameref="something something"

printf '%s\n' "$host_file"

This would output the string something something. Using typeset -n in place of declare -n would make it work in both bash and in ksh93.

  • I have actually tried this but declare doesn't have -n option and couldn't go further. – Rajesh Reddy B Feb 19 '18 at 10:16
  • @RajeshReddyB This indicates that your bash is older than release 4.3. – Kusalananda Feb 19 '18 at 10:17
1

If you have variables named as a combination of some proper name, and related attributes you should probably use associative arrays instead. Assuming you have Bash 4.x, ksh or zsh, that is. See a page or another on BashGuide. (Actually structures like in C would be nice, but you can't really get that with Bash.)

That is, to store a URL and a port for the hosts/clusters oregon and arizona, don't make four variables arizona_url, arizona_port, oregon_url, oregon_port, but instead something like this:

typeset -A urls ports
urls[oregon]="http://..."
urls[arizona]="http://..."
ports[oregon]=1234
ports[arizona]=2345

and then use those with "${urls[$hostname1]}", "${ports[$hostname]}" etc.

0

As per the previous answer, you can use eval for this.

eval [arg ...] The args are read and concatenated together into a single com‐ mand. This command is then read and executed by the shell, and its exit status is returned as the value of eval. If there are no args, or only null arguments, eval returns 0. (from bash man page)

However, this is one of those bad programming habits that you need to be very aware of and use as little as possible. It can normally be avoided for something more elegant, less error-prone and easier to debug.

var1=host
eval echo ${var1}_file # print contents of $host_file
  • ${!var1} is as dangerous as eval if the content of $var1 may be under the control of an attacker. That code is not correct, it should have been eval 'echo "${'"$var1"'_file}"' – Stéphane Chazelas Oct 24 '18 at 14:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.