Bash obtient la longueur de l'expansion de variable indirecte avec une liste comme variable

Oct 17 2020

Alors disons que nous avons:

a=(1 2 3 4)
b=a

Je veux obtenir la longueur de a à b Une façon pourrait être:

a=(1 2 3 4)
b="a[@]"
c=("${!b}") echo ${#c[@]}

mais je suis intéressé de voir s'il existe une solution sans la variable supplémentaire

Réponses

3 StéphaneChazelas Oct 17 2020 at 02:46

Pour mémoire, dans zsh, où l'équivalent de bash's ${!b}est ${(P)b}(et où ${#array[@]}peut aussi être écrit $#arraycomme dans csh)

$ a=(1 2 3 4) b=a $ echo ${(P)#b}
4

Dans bash, si vous vouliez vraiment utiliser l' ${!b}indirection, vous pouvez toujours faire:

$ a=(1 2 3 4) $ b='b[(b=${#a[@]}),0]' $ echo "${!b}"
4

Vous pouvez utiliser le même genre d'astuce pour avoir une variable qui se développe dynamiquement au nombre d'éléments $aavec:

$ typeset -n b='x[(x=${#a[@]}),0]'
$ echo "$b"
4
$ a+=(more) $ echo "$b"
5

(ici en utilisant xau lieu de bcomme se bashplaint si le nameref se réfère à lui-même).

Ou vous pouvez toujours utiliser eval:

$ a=(1 2 3 4) b=a
$ eval 'echo "${#'"$b"'[@]}"'
4
3 glennjackman Oct 17 2020 at 02:05

Avec les variables indirectes, c'est ainsi que vous devez le faire.

Avec namerefs (bash 4.3+), vous pouvez faire

a=(1 2 3 4)
declare -n b=a
echo "${#b[@]}"