Usually I find solutions for more complex tasks in shell scripts by breaking down longer commands into a sequence of simple commands. Here is one where I couldn't find a solution with this method.
I need to do calculations, in order to know which argument I need to use. Once I have it, I can call it, like here (simplified, generic version):
1 i=1
2 k=$(( i+1 ))
3 echo $i
4 echo $k
5 echo "${!i}"
6 echo "${!k}"
As to be expected:
$ ./testo A B
1
2
A
B
Firstly, I found that expression with an exclamation mark somewhere in the Interwebs, and I was happy to have it, because it works. I don't understand what it does, however.
In my opinion, !
usually means not
, but here it exactly works. Without, however, it doesn't. I'd like to learn, why.
Now I wanted to simplify the code, and remove the - I think - unnecessary second line by substituting the k
in the last line with an arithmetic expression, as in line 2.
To my surprise, neither of my efforts of copying the expression for k
from the second line actually works:
1 i=1
2 k=$(( i+1 ))
3 echo $i
4 echo $k
5 echo "${!i}"
6 echo "${!k}"
7 echo "${!$(( i+1 ))}"
8 echo "${!(( i+1 ))}"
9 echo "${!(( $i+1 ))}"
, as can be seen here:
./testo: line 7: ${!$(( i+1 ))}: bad substitution
./testo: line 8: ${!(( i+1 ))}: bad substitution
./testo: line 9: ${!(( $i+1 ))}: bad substitution
What do I do wrong; what would be a good substition; why can't I just copy the expression for k
of line 2 into the place of k
in line 6?
Expansions are not macros. To expand you have to have a variable. You can't optimize it. It's fine, presented code is perfect.
I don't understand what it doe
Indirect expansion is documented in bash manual. See What is indirect expansion? What does ${!var*} mean? and https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html .
and remove the - I think - unnecessary second line by substituting the k in the last line with an arithmetic expression, as in line 2
No possible.
What do I do wrong
Nothing.
what would be a good substition
k=$(( i+1 )); echo "${!k}"
is perfect substitution
why can't I just copy the expression for k of line 2 into the place of k in line 6?
Expansions are not macros. The ${!
has to expand a variable. You can't chain expansions, they are just not parsed or implemented that way.