Je lis "Bash Guide for Beginners". Ça dit:
Si le premier caractère de
PARAMETER
est un point d'exclamation, Bash utilise la valeur de la variable formée à partir du reste dePARAMETER
comme nom de la variable; cette variable est ensuite développée et cette valeur est utilisée dans le reste de la substitution, plutôt que la valeur dePARAMETER
elle-même. C'est ce qu'on appelle l'expansion indirecte.
L'exemple donné est:
franky ~> echo ${!N*} NNTPPORT NNTPSERVER NPX_PLUGIN_PATH
Je ne comprends pas très bien ici:
la valeur de la variable formée du reste de
PARAMETER
Comme le PARAMETER
est juste !N*
, puis
le reste de
PARAMETER
est juste N*
. Comment cela pourrait-il former une variable? Bash a-t-il cherché toutes les commandes possibles là-bas?
Si vous lisez la page de manuel bash
, cela confirme essentiellement ce que vous avez déclaré:
Si le premier caractère du paramètre est un point d'exclamation (
!
), un niveau d'indirection variable est introduit. Bash utilise la valeur de la variable formée à partir du reste du paramètre comme nom de la variable; cette variable est ensuite développée et cette valeur est utilisée dans le reste de la substitution, plutôt que la valeur du paramètre lui-même. C'est ce qu'on appelle l'expansion indirecte.
Cependant, en lisant à partir de là:
Les exceptions à cette règle sont les extensions de
${!prefix*}
et${!name[@]}
décrit ci-dessous.
${!prefix*}
Noms correspondant au préfixe. Se développe en noms de variables dont les noms commencent par un préfixe, séparés par le premier caractère de la variable spécialeIFS
.
En d'autres termes, votre exemple particulier ${!N*}
est une exception à la règle que vous avez citée. Il fonctionne , cependant, fonctionne comme annoncé dans les cas attendus, tels que:
$ export xyzzy=plugh ; export plugh=cave
$ echo ${xyzzy} # normal, xyzzy to plugh
plugh
$ echo ${!xyzzy} # indirection, xyzzy to plugh to cave
cave
Il semble y avoir une exception lorsque "l'indirection" donnée se termine par un *
, comme ici. Dans ce cas, il donne tous les noms de variables qui commencent par la partie que vous avez spécifiée (N
ici). Bash peut le faire car il suit les variables et sait lesquelles existent.
La véritable indirection est la suivante:
Disons que j'ai une variable $VARIABLE
mis à 42
, et j'ai une autre variable $NAME
défini sur VARIABLE
. ${!NAME}
me donnera 42
. Vous utilisez la valeur d'une variable pour vous indiquer le nom d'une autre:
$ NAME="VARIABLE"
$ VARIABLE=42
$ echo ${!NAME}
42
Oui, il recherche toutes les extensions possibles de variables après le!. Si vous l'aviez fait:
echo ${!NP*}
vous obtiendrez seulement NPX_PLUGIN_PATH
.
Prenons l'exemple suivant:
:~> export myVar="hi"
:~> echo ${!my*}
myVar
:~> export ${!my*}="bye"
:~> echo $myVar
bye
Vous avez rencontré une exception dans le traitement d'indirection, où si le dernier caractère est *
, toutes les variables qui ont le préfixe donné avant seront retournées.
Vous pouvez vous référer à ce document GNU pour bash pour des informations faisant autorité
Mais fondamentalement, l'expansion indirecte n'est pas effectuée sur ${!prefix*}
comme l'une des exceptions, dans votre exemple, N est le préfixe.
Le document expliquera ce qu'est l'expansion indirecte dans bash