1

Yes, yes, I know you're probably like "Hey, there are hundreds of other people asking this same question", but that's not true; I'm not trying to do something like this:

foo="example1"
bar="example2"
foobar="$foo$bar"

I'm trying to do this:

foo="example1"
$foo="examle2"

But whenever I attempt this, I get an error message that says:

bash: example1=example2: command not found

Any suggestions? Is this even possible?

  • Yea, there have been a couple of questions of just this within a day or two. I tried to look but didn't find an answer that would deal with all the usual use-cases. So, @Anon, do you have a particular use case in mind? What you're doing might be better done with arrays or associative arrays. – ilkkachu Aug 22 '18 at 19:47
  • @ilkkachu to answer your question, I was using an array that cycled through numbers and then I made a variable for each one that was named whatever variable was selected. The contents of the variable were some text files. So, basically, I was trying to EFFICIENTLY make a textfile updater. – Anonymous Aug 22 '18 at 21:41

3 Answers3

6

Here are some examples:

declare [-g] "${foo}=example2"
declare -n foo='example1'
foo='example2'
eval "${foo}=example2"
mapfile -t "${foo}" <<< 'example2'
printf -v "${foo}" '%s' 'example2'
IFS='' read -r "${foo}" <<< 'example2'
typeset [-g] "${foo}=example2"

As other users said, be careful with eval and with indirect assignments in general.

nxnev
  • 3,654
  • Oh duh! I completely forgot declare and eval! Thanks so much! After testing both, eval worked "letter-for-letter", and declare worked once I removed the [ ]s from the first declare code. – Anonymous Aug 22 '18 at 21:35
  • @AnonymousUser216 Those brackets mean that the -g option is, well, optional, so it may or may not be present in the actual command (read the synopsis of some man pages to see more examples of this syntax). If you use declare var inside a function, then var will be local; but if you use declare -g var, then var will be global. Although, according to Stéphane Chazelas, the actual explanation is a bit more complicated. – nxnev Aug 22 '18 at 22:17
  • Trying again, I ran into another problem; I can't assign variable values using your method that have variables in them. Like eval "${foo}='some text'$bar" outputs Command not found. Help? – Anonymous Aug 22 '18 at 23:32
  • @Anon What's the content of ${bar}? Remember that eval is used in this case to trigger 2 "levels" of execution instead of only one: the first one by the shell (which expands ${foo}) and the second one by eval itself (which runs example1=example2 as shell code in the current context). So, if ${bar} holds some value like word1 word2, what eval sees is example1='some text'word1 word2, thus it interprets word1 as part of the assignment, word2 as a command and it tries to export the example1 variable to the word2 command's environment (which doesn't exist, does it?). – nxnev Aug 23 '18 at 00:16
  • ${bar} is just one word, but don’t worry, I figured out my problem; ${foo}’s value was a number. -silent facepalm- I had forgotten you couldn’t use plain numbers as variables. I added ‘s’ to the front and it worked like a charm. Thank you for your input, though! – Anonymous Aug 23 '18 at 11:13
0

It is possible using eval.

eval $foo="examle2"

Be aware that you should be very sure that the value of $foo can be trusted.

A better alternative is to used indexed arrays, where you don't risk executing arbitrary commands.

RalfFriedl
  • 8,981
0
suffix=bzz
declare -g prefix_$suffix=mystr

...and then...

varname=prefix_$suffix
echo ${!varname}

Shamelessly stolen from here.

Edit: As stated by Stephane this is generally a bad idea and should be avoided. Indexed arrays are a better alternative.