¿Qué es la expansión indirecta? ¿Qué significa $ {! Var *}?

Estoy leyendo ” Bash Guide for Beginners “. Dice:

Si el primer carácter de PARAMETER es un signo de exclamación, Bash usa el valor de la variable formada a partir del rest de PARAMETER como el nombre de la variable; esta variable luego se expande y ese valor se usa en el rest de la sustitución, en lugar del valor de PARAMETER mismo. Esto se conoce como expansión indirecta.

El ejemplo dado es:

 franky ~> echo ${!N*} NNTPPORT NNTPSERVER NPX_PLUGIN_PATH 

No entiendo muy bien aquí:

el valor de la variable formada a partir del rest de PARAMETER

Como el PARAMETER es simplemente !N* , entonces

el rest de PARAMETER

es solo N* . ¿Cómo podría esto formar una variable? ¿Bash buscó todos los comandos posibles allí?

Si lees la página del hombre bash , básicamente confirma lo que has dicho:

Si el primer carácter de parámetro es un signo de exclamación ( ! ), Se introduce un nivel de indirección variable. Bash usa el valor de la variable formada a partir del rest del parámetro como el nombre de la variable; esta variable luego se expande y ese valor se usa en el rest de la sustitución, en lugar del valor del parámetro en sí mismo. Esto se conoce como expansión indirecta.

Sin embargo, leyendo desde allí:

Las excepciones a esto son las expansiones de ${!prefix*} y ${!name[@]} describen a continuación.

${!prefix*} Nombres que coinciden con el prefijo. Se expande a los nombres de variables cuyos nombres comienzan con el prefijo, separados por el primer carácter de la variable especial IFS .

En otras palabras, su ejemplo particular ${!N*} es una excepción a la regla que citó. Sin embargo, funciona como se anuncia en los casos esperados, como por ejemplo:

 $ export xyzzy=plugh ; export plugh=cave $ echo ${xyzzy} # normal, xyzzy to plugh plugh $ echo ${!xyzzy} # indirection, xyzzy to plugh to cave cave 

Parece haber una excepción cuando la “indirección” dada termina en un * , como lo hace aquí. En este caso, proporciona todos los nombres de variables que comienzan con la parte que especificó ( N aquí). Bash puede hacerlo porque rastrea las variables y sabe cuáles existen.

La verdadera indirección es esta:
Digamos que tengo una variable $VARIABLE establecida en 42 , y tengo otra variable $NAME establecida en VARIABLE . ${!NAME} me dará 42 . Usas el valor de una variable para decirte el nombre de otra:

 $ NAME="VARIABLE" $ VARIABLE=42 $ echo ${!NAME} 42 

Sí, busca todas las posibles expansiones de variables después del! Si hubieras hecho:

 echo ${!NP*} 

solo obtendrías NPX_PLUGIN_PATH .

Considere el siguiente ejemplo:

 :~> export myVar="hi" :~> echo ${!my*} myVar :~> export ${!my*}="bye" :~> echo $myVar bye 

Ha accedido a una excepción en el procesamiento indirecto, donde si el último carácter es * , se devolverán todas las variables que tengan el prefijo anterior.