4

Any ideas why this is happening? Why do I have to manually explicitly reassign the variable but can't do it if I have another variable in the name of the variable?

SCRIPT:

#!/bin/bash

a_1=1
a_2=1

for temp in 1 2
do
    a_$temp="2"
    echo $((a_$temp))
done

a_1=2
a_2=2
echo $a_1
echo $a_2

OUTPUT:

[dgupta@della4 Rates_Of_Quenching]$ ./test.sh
./test.sh: line 8: a_1=2: command not found
1
./test.sh: line 8: a_2=2: command not found
1
2
2
julienc
  • 19,087
  • 17
  • 82
  • 82

2 Answers2

5

Instead of:

a_$temp="2"

Use:

declare a_$temp="2"

to create variable with dynamic name.

anubhava
  • 761,203
  • 64
  • 569
  • 643
2

As far as bash is concerned, you are trying to execute the command 'a_1=2', rather than perform an assignment. You can get around this by using declare, or its synonym typeset:

'a_1=2'                       # bash: a_1=2: command not found
typeset 'a_1=2' 
echo $a_1                     # 2
declare 'a_1=3'
echo $a_1                     # 3

While it is possible to use declare, you might want to take advantage of bash arrays (which have been around since bash version 2) rather than using variables with numerical suffixes:

a=(1 1)
echo ${a[0]}                  # 1
echo ${a[1]}                  # 1
for i in 0 1; do a[i]=2; done
echo ${a[0]}                  # 2
echo ${a[1]}                  # 2
Tom Fenech
  • 72,334
  • 12
  • 107
  • 141
  • +1, but (a) `bash` considers `typeset` obsolete (it still has its place if maximum portability is required) and (b) your inclusion of a prompt string (`bash-4.3$`) both creates visual noise and makes it harder to copy-paste your code for verification (it's commendable to state the `bash` version your code was run on, but that could be done separately, although, depending on the feature discussed, stating the version may not be necessary at all, if a feature was introduced a loooong time ago). – mklement0 Jun 04 '14 at 21:13
  • You're welcome; I was actually thinking of _not using a prompt string at all_ (even just `$`), as it makes copy-pasting any _sequence_ of commands cumbersome. I know that `$` is seductive, because it is widely used to symbolize a prompt, whereas I know of no equally well-known symbol to indicate _output_ (is there one?). However, I think on SO reversing the logic is beneficial: _no_ prefix for the _commands_, and some indicator for _output_. One - not very elegant - way around this is to place output in a _separate_ code snippet. – mklement0 Jun 04 '14 at 21:40
  • @mklement0 I agree with your thoughts. For a longer script, I would normally show the output separately. I've edited to show the output of the commands in comments, which at least means that the commands can be directly copy-pasted. – Tom Fenech Jun 04 '14 at 21:51
  • Good idea; placing the output in _comments_ is a simpler alternative. – mklement0 Jun 04 '14 at 21:53
  • @mklement0 of course, my answer would have been three times as well appreciated if I'd instead displayed no output, provided no explanation but _crucially_ got there first. Not that I'm bitter ;) Thanks again for your feedback. – Tom Fenech Jun 04 '14 at 22:00
  • :) Thanks for _listening_ to my feedback. Truthfully, different styles of answers are useful to different audiences at different times. The quick-and-dirty answers are sometimes more useful if you're a newbie and just want an answer without getting confused by TMI; however, over time a more thorough answer like yours may also find its audience. – mklement0 Jun 04 '14 at 22:19