9.5. Références indirectes

Nous avons vu que lorsqu'on référence une variable, $var, on obtient sa valeur. Mais que dire de la valeur d'une valeur ? Que penser de $$var ?

En fait, la notation correcte est \$$var, généralement précédée d'un eval (et parfois aussi un echo). Cela s'appelle une référence indirecte.

Exemple 9.24. Références indirectes aux variables

&indref;

Quel est l'intérêt pratique des références indirectes aux variables ? Cela donne à Bash une partie de la fonctionnalité des pointeurs, comme en C, par exemple dans la recherche dans des tables. Et, cela a aussi quelques autres applications intéressantes...

Nils Radtke montre comment construire des noms de variables « dynamiques » et comment évaluer leur contenu. Ceci peut être utile pour l'intégration de fichiers de configuration.

#!/bin/bash


# ---------------------------------------------
# Ceci pourrait être "récupéré" d'un fichier séparé.
isdnMonFournisseurDistant=172.16.0.100
isdnTonFournisseurDistant=10.0.0.10
isdnServiceInternet="MonFournisseur"
# ---------------------------------------------


netDistant=$(eval "echo \$$(echo isdn${isdnServiceInternet}Distant)")
netDistant=$(eval "echo \$$(echo isdnMonFournisseurDistant)")
netDistant=$(eval "echo \$isdnMonFournisseurDistant")
netDistant=$(eval "echo $isdnMonFournisseurDistant")

echo "$netDistant"    # 172.16.0.100

# ================================================================

#  Et cela devient encore meilleur.

#  Considérez l'astuce suivant étant donnée une variable nommée getSparc,
#+ mais sans variable getIa64 :

chkMirrorArchs () {
  arch="$1";
  if [ "$(eval "echo \${$(echo get$(echo -ne $arch |
        sed 's/^\(.\).*/\1/g' | tr 'a-z' 'A-Z'; echo $arch |
        sed 's/^.\(.*\)/\1/g')):-false}")" = true ]
  then
    return 0;
  else
    return 1;
  fi;
}

getSparc="true"
unset getIa64
chkMirrorArchs sparc
echo $?        # 0
               # True

chkMirrorArchs Ia64
echo $?        # 1
               # False

# Notes :
# ------
# Même la partie du nom de la variable à substituer est construite explicitement.
# Les paramètres des appels de chkMirrorArchs sont tous en minuscule.
# Le nom de la variable est composé de deux parties : "get" et "Sparc" . . .

Exemple 9.25. Passer une référence indirecte à awk

&coltotaler2;

[Attention]

Attention

Cette méthode de référence indirecte est un peu délicate. Si la variable de second ordre change de valeur, alors la variable de premier ordre doit être correctement déréférencée (comme sur l'exemple ci-dessus). Heureusement, la notation ${!variable} introduite avec la version 2 de Bash (voir l'Exemple 34.2, « Références de variables indirectes - la nouvelle façon » et l'Exemple A.22, « Pour en savoir plus sur les fonctions de hachage ») rend les références indirectes plus intuitives.