Shell – Define variables with a variable name

shell-scriptvariable

What's wrong with this script?
I'm trying to define A1=1, B1=1, C1=1

LIST="A B C"
for x in $LIST
do
    "$x"1=1
done

and the result is:

./x.: line 7: A1=1: command not found
./x.: line 7: B1=1: command not found
./x.: line 7: C1=1: command not found

Best Answer

A variable assignment has the form of a variable name, followed by the equal sign, followed by the (optional) value.

This is a valid assignment:

ABC=123

"$x"1=1 is not a valid assignment, because "$x"1 is not a variable name. It may be evaluated to a variable name, but it isn't. The shell, in fact, believes it is a command.

One way for doing what you want to achieve is this:

eval "$x"1=1

Another way in bash (but not in other shells) is:

declare "$x"1=1

Or also (again bash-only):

let "$x"1=1

(There is no much difference in your case.)

But, as Jakuje noted in the comments, you probably want to go with arrays, if your shell has them (ksh, bash or zsh).


For completeness:

  • eval executes arbitrary commands. So, if on the right side of the equal sign you have a variable that expands to some command, that command will be executed. The following code:

    x=a
    y='$(echo hello)'
    eval "$x=$y"
    

    is equivalent to a=hello.

  • declare is a bash builtin to assign variables and won't execute any command. The following code:

    x=a
    y='$(echo hello)'
    declare "$x=$y"
    

    is equivalent to a='$(echo hello)'.

  • let is similar to declare, in that it doesn't execute commands. But contrary to declare, let may be used for arithmetic operations:

    let a="1 + 2"
    

    is equivalent to a=3.

Related Question