Un puntero (a una ubicación de memoria ) no es realmente un concepto útil en algo de nivel superior a C, ya sea algo como Python o el shell. Las referencias a objetos son, por supuesto, útiles en lenguajes de alto nivel, tal vez incluso necesarios para construir estructuras de datos complejas. Pero en la mayoría de los casos, pensar en términos de direcciones de memoria es un nivel demasiado bajo para ser muy útil.
En Bash (y otros shells), puede obtener los valores de los elementos de la matriz con la ${array[index]}
notación, asignarlos array[index]=...
y obtener el número de elementos en la matriz con ${#array[@]}
. La expresión dentro de los corchetes es una expresión aritmética. Como ejemplo inventado, podríamos agregar un prefijo constante a todos los miembros de la matriz:
for ((i=0 ; i < ${#array[@]} ; i++ )) ; do
array[i]="foo-${array[i]}"
done
(Si solo nos preocuparan los valores, y no los índices, for x in "${array[@]}" ; do...
estaría bien).
Con matrices asociativas o dispersas , un bucle numérico no tiene mucho sentido, pero en su lugar tendríamos que buscar las claves / índices de la matriz ${!array[@]}
. P.ej
declare -A assoc=([foo]="123" [bar]="456")
for i in "${!assoc[@]}" ; do
echo "${assoc[$i]}"
done
Además de eso, Bash tiene dos formas de señalar indirectamente a otra variable:
- expansión indirecta , usando la
${!var}
sintaxis , que usa el valor de la variable cuyo nombre está en var
, y
- namerefs , que deben crearse con la función
declare
incorporada (o el ksh
sinónimo compatible typeset
). declare -n ref=var
hace ref
una referencia a la variable var
.
Namerefs también admite la indexación, ya que si lo hemos hecho arr=(a b c); declare -n ref=arr;
, ${ref[1]}
se expandirá a b
. En su lugar, usar ${!p[1]}
tomaría p
como una matriz y se referiría a la variable nombrada por su segundo elemento.
En Bash, namerefs es literalmente eso, las referencias por nombre y el uso de un nameref desde dentro de una función usarán el valor local de la variable nombrada. Esto se imprimirá local value of var
.
#!/bin/bash
fun() {
local var="local value of var"
echo "$ref";
}
var="global var"
declare -n ref=var
fun
BashFAQ también tiene un artículo más largo sobre indirección .
for foo in "${array[@]}" ; do ... done
menos que necesite el índice para otro (s) propósito (s).No,
bash
no tiene "punteros", pero tiene referencias:Desde la
bash
página del manual:fuente
No, los shells no usan "punteros" (como se entiende en C).
Las matrices podrían usar índices:
echo "${array[2]}"
pero@
en su ejemplo no es realmente un "puntero". Es una forma de expresar "la lista de valores de la matriz". Algo que entiende el analizador de shell. Similar a la forma en que:se expande a toda la lista de "Parámetros posicionales".
fuente
Mientras que las matrices indexadas de bash integer se pueden definir y acceder de forma iterativa de esta manera;
Las matrices indexadas asociativas o basadas en cadenas en bash requieren la siguiente definición iterativa;
Para responder la pregunta sobre punteros y usar uno de bash; la funcionalidad interna del binario bash compilado de hecho hace uso de punteros a la memoria asignada en la pila y expone una funcionalidad similar con el uso de
eval
. Ver [referencias indirectas] http://tldp.org/LDP/abs/html/ivr.html )Habrá dragones; el uso de
eval
debe usarse con precaución debido a implicaciones de seguridadfuente