Lo que dice el título: ¿qué significa encapsular una variable en {}
, ""
o "{}
"? No he podido encontrar ninguna explicación en línea sobre esto, no he podido referirme a ellos excepto por el uso de los símbolos, que no produce nada
Aquí hay un ejemplo:
declare -a groups
groups+=("CN=exampleexample,OU=exampleexample,OU=exampleexample,DC=example,DC=com")
groups+=("CN=example example,OU=example example,OU=example example,DC=example,DC=com")
Esta:
for group in "${groups[@]}"; do
echo $group
done
Demuestra ser muy diferente a esto:
for group in $groups; do
echo $group
done
y esto:
for group in ${groups}; do
echo $group
done
Solo el primero logra lo que quiero: recorrer cada elemento de la matriz. No estoy muy claro en las diferencias entre $groups
, "$groups"
, ${groups}
y "${groups}"
. Si alguien pudiera explicarlo, lo agradecería.
Como pregunta adicional, ¿alguien sabe la forma aceptada de referirse a estas encapsulaciones?
bash
script?Respuestas:
Tirantes (
$var
vs.${var}
)En la mayoría de los casos,
$var
y${var}
son lo mismo:Las llaves solo son necesarias para resolver la ambigüedad en las expresiones:
Cotizaciones (
$var
vs."$var"
vs."${var}"
)Cuando agrega comillas dobles alrededor de una variable, le dice al shell que la trate como una sola palabra, incluso si contiene espacios en blanco:
Contraste ese comportamiento con lo siguiente:
Al igual que con
$var
vs.${var}
, las llaves solo son necesarias para la desambiguación, por ejemplo:Tenga
"${var}bar"
en cuenta que en el segundo ejemplo anterior también podría escribirse"${var}"bar
, en cuyo caso ya no necesitará las llaves, es decir"$var"bar
. Sin embargo, si tiene muchas citas en su cadena, estas formas alternativas pueden ser difíciles de leer (y, por lo tanto, difíciles de mantener). Esta página proporciona una buena introducción a las citas en Bash.Arreglos (
$var
vs.$var[@]
vs.${var[@]}
)Ahora para tu matriz. De acuerdo con el manual de bash :
En otras palabras, si no proporciona un índice
[]
, obtiene el primer elemento de la matriz:Que es exactamente lo mismo que
Para obtener todos los elementos de una matriz, debe usar
@
como índice, por ejemplo${foo[@]}
. Las llaves se requieren con las matrices porque sin ellas, el shell expandiría la$foo
parte primero, dando el primer elemento de la matriz seguido de un literal[@]
:Esta página es una buena introducción a las matrices en Bash.
Cotizaciones revisitadas (
${foo[@]}
vs."${foo[@]}"
)No preguntaste sobre esto, pero es una sutil diferencia que es bueno saber. Si los elementos en su matriz pueden contener espacios en blanco, debe usar comillas dobles para que cada elemento sea tratado como una "palabra" separada.
Compare esto con el comportamiento sin comillas dobles:
fuente
${var:?}
que proporcionará un error cuando la variable se desarma o no se configura. REF: github.com/koalaman/shellcheck/wiki/SC2154${parameter:-word}
,${parameter:=word}
,${parameter#word}
,${parameter/pattern/string}
, y así sucesivamente. Creo que están más allá del alcance de esta respuesta.TL; DR
Todos los ejemplos que da son variaciones de las expansiones de Bash Shell . Las expansiones ocurren en un orden particular, y algunas tienen casos de uso específicos.
Aparatos ortopédicos como delimitadores de tokens
La
${var}
sintaxis se usa principalmente para delimitar tokens ambiguos. Por ejemplo, considere lo siguiente:Tirantes en expansiones de matriz
Las llaves se requieren para acceder a los elementos de una matriz y para otras expansiones especiales . Por ejemplo:
Tokenización
La mayoría del resto de sus preguntas tienen que ver con las citas y cómo el shell tokeniza la entrada. Considere la diferencia en cómo el shell realiza la división de palabras en los siguientes ejemplos:
El @símbolo interactúa con las citas de manera diferente a *. Específicamente:
$@
"[e] xpands a los parámetros posicionales, comenzando desde uno. Cuando la expansión se produce entre comillas dobles, cada parámetro se expande a una palabra separada".${name[*]}
expande a una sola palabra con el valor de cada miembro de la matriz separado por el primer carácter de la variable IFS, y${name[@]}
expande cada elemento de nombre a una palabra separada".Puede ver esto en acción de la siguiente manera:
El uso de una expansión entre comillas es muy importante cuando las variables se refieren a valores con espacios o caracteres especiales que podrían evitar que el shell divida las palabras de la manera que desea. Consulte Citas para obtener más información sobre cómo funcionan las citas en Bash.
fuente
Debe distinguir entre matrices y variables simples, y su ejemplo es utilizar una matriz.
Para variables simples:
$var
y${var}
son exactamente equivalentes"$var"
y"${var}"
son exactamente equivalentesSin embargo, los dos pares no son 100% idénticos en todos los casos. Considere la salida a continuación:
Sin las comillas dobles alrededor de la variable, el espacio interno se pierde y la expansión se trata como dos argumentos para el
printf
comando. Con las comillas dobles alrededor de la variable, se conserva el espacio interno y la expansión se trata como un argumento para elprintf
comando.Con las matrices, las reglas son similares y diferentes.
groups
es una matriz, que hace referencia$groups
o${groups}
es equivalente a una referencia${groups[0]}
, el elemento cero de la matriz."${groups[@]}"
es análoga a la referencia"$@"
; conserva el espacio en los elementos individuales de la matriz y devuelve una lista de valores, un valor por elemento de la matriz.${groups[@]}
sin las comillas dobles no conserva el espacio y puede introducir más valores que elementos en la matriz si algunos de los elementos contienen espacios.Por ejemplo:
Usar en
*
lugar de@
conduce a resultados sutilmente diferentes.Consulte también Cómo iterar sobre los argumentos en un
bash
script .fuente
La segunda oración del primer párrafo bajo Expansión de parámetros en
man bash
dice:Lo que le dice que el nombre es simplemente llaves , y el propósito principal es aclarar dónde comienza y dónde termina el nombre:
Si lees más, descubres,
Probemos:
Huh Ordenado. Honestamente, no sabía eso antes de escribir esto (nunca antes había tenido más de 9 parámetros posicionales).
Por supuesto, también necesita llaves para realizar las potentes funciones de expansión de parámetros como
así como la expansión de la matriz.
fuente
Un caso relacionado no cubierto anteriormente. Citar una variable vacía parece cambiar las cosas
test -n
. Esto se da específicamente como un ejemplo en elinfo
texto paracoreutils
, pero no se explica realmente:Me encantaría escuchar la explicación detallada. Mi prueba confirma esto, y ahora estoy citando mis variables para todas las pruebas de cadena, para evitar tener
-z
y-n
devolver el mismo resultado.fuente
Bueno, sé que la encapsulación de una variable te ayuda a trabajar con algo como:
o una sintaxis como esa, donde desea hacer algo con su variable antes de devolver el valor.
Ahora, si ves tu código, toda la magia está dentro
la magia está ahí porque no puedes escribir solo:
$groups[@]
Estás poniendo tu variable dentro de
{}
porque quieres usar caracteres especiales[]
y@
. No puede nombrar o llamar a su variable solo:@
osomething[]
porque estos son caracteres reservados para otras operaciones y nombres.fuente