My attempts seem to complicate the task too much
A task may look easy, but it cannot be a normal use case and therefore does not have syntactic sugar to simplify it, especially if you can use other built-in functions to complete it.
You have many alternatives, here is another one:
put_first_index_in () { printf -v "${1?}" "%s" "${2?}" } put_first_index_in first_index "${!arr[@]}"
What really happens in $ {! arr [@]: 0: 1}?
Indirect expansion of variables :
If the first character of the parameter is an exclamation point ( ! ), And the parameter is not nameref, it enters the level of the Indirect variable. Bash uses the value of a variable formed from the rest of the parameter as the name of the variable; this variable is then expanded, and this value is used in the rest of the substitution, not the value of the parameter itself. This is called indirect expansion .
C ! three possible things are supported as the first character: ${!parameter} (the specified indirect extension), ${!prefix*} , ${ !prefix@ } (expand to the names of the variables corresponding to prefix ), and ${!name[*]} , ${!name[@]} (expand indexes of the name array).
The docs assume that only ${!parameter} supports further substitution, since it is only mentioned for this, and not for others. Therefore, Bash is trying to do the following:
- Expand
arr[@] - Apply the indirect extension to the string obtained from (1)
- Get the substring
0:1 from the string obtained from the indirect extension
As is not a valid character in identifiers, we get this error:
$ foo=SHELL $ echo ${!foo} /bin/zsh $ echo ${!foo:0:1} / $ foo="SHELL " $ echo ${!foo} bash: SHELL : bad substitution $ arr=([2]=SHELL bbb ccc ddd) $ echo ${!arr[@]:0:1} bash: SHELL bbb ccc ddd: bad substitution
Thus, this will only work with arrays of one element, for example:
$ arr=([2]=SHELL)
And as expected:
$ echo ${!arr[@]:0:1} /