web-dev-qa-db-fra.com

Qu'est-ce que l'expansion indirecte? Que signifie $ {! Var *}?

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 de PARAMETER 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 de PARAMETER 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?

68
athos

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éciale IFS.

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
87
paxdiablo

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
19
Kevin

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
3
tpg2114

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.

2

Vous pouvez vous référer à ce document GNU pour bash pour des informations faisant autorité

https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html#Shell-Parameter-Expansion

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

0
Margach Chris