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.
Quel est l'intérêt pratique des références indirectes aux variables ? Cela donne à Bash une partie de la fonctionnalité des pointeurs de C, par exemple dans la recherche dans des tables. Entre autres applications intéressantes...
Nils Radtke montre comment construire des noms de variables « dynamiques » et comment évaluer leur contenu. Cela peut être utile pour l'intégration de fichiers de configuration.
#!/bin/bash # --------------------------------------------- # Ceci pourrait être "récupéré" à partir 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 # ================================================================ # Ensuite c'est encore meilleur. # Considérez l'astuce suivante é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 à chkMirrorArchs sont tous en minuscule. # Le nom de la variable est composé de deux parties : "get" et "Sparc" . . .
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). Fort heureusement, la notation ${!variable} introduite dans la version 2 de Bash (voir l'Exemple 37.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.