¿Cuándo necesitamos aparatos ortopédicos alrededor de las variables de la carcasa?

En scripts de shell, ¿cuándo usamos {} al expandir variables?

Por ejemplo, he visto lo siguiente:

 var=10 # Declare variable echo "${var}" # One use of the variable echo "$var" # Another use of the variable 

¿Hay una diferencia significativa, o es solo estilo? ¿Se prefiere uno sobre el otro?

En este ejemplo particular, no hace ninguna diferencia. Sin embargo, {} en ${} son útiles si desea expandir la variable foo en la cadena

 "${foo}bar" 

ya que "$foobar" su lugar expandiría foobar .

Las llaves también se requieren incondicionalmente cuando:

  • expandiendo los elementos de la matriz, como en ${array[42]}
  • usando operaciones de expansión de parámetros, como en ${filename%.*} (eliminar extensión)
  • expandir los parámetros posicionales más allá de 9: "$8 $9 ${10} ${11}"

Hacer esto en todas partes, en lugar de solo en casos potencialmente ambiguos, puede considerarse una buena práctica de progtwigción. Esto es tanto por coherencia como para evitar sorpresas como $foo_$bar.jpg , donde no es visualmente obvio que el guión bajo se convierta en parte del nombre de la variable.

Las variables se declaran y asignan sin $ y sin {} . Tienes que usar

 var=10 

asignar. Para leer de la variable (en otras palabras, ‘expandir’ la variable), debe usar $ .

 $var # use the variable ${var} # same as above ${var}bar # expand var, and append "bar" too $varbar # same as ${varbar}, ie expand a variable called varbar, if it exists. 

Esto me ha confundido a veces, en otros idiomas nos referimos a la variable de la misma manera, independientemente de si está a la izquierda oa la derecha de una tarea. ¡Pero el shell-scripting es diferente, $var=10 no hace lo que crees que hace!

Usas {} para agrupar. Las llaves se requieren para desreferenciar los elementos de la matriz. Ejemplo:

 dir=(*) # store the contents of the directory into an array echo "${dir[0]}" # get the first entry. echo "$dir[0]" # incorrect 

También puedes hacer algo de manipulación de texto dentro de las llaves:

 STRING="./folder/subfolder/file.txt" echo ${STRING} ${STRING%/*/*} 

Resultado:

 ./folder/subfolder/file.txt ./folder 

o

 STRING="This is a string" echo ${STRING// /_} 

Resultado:

 This_is_a_string 

Tiene razón en “variables regulares” que no son necesarias … Pero es más útil para la depuración y para leer un guión.

El final del nombre de la variable suele estar representado por un espacio o nueva línea. Pero, ¿qué pasa si no queremos un espacio o línea nueva después de imprimir el valor de la variable? Las llaves le dicen al intérprete de shell dónde está el final del nombre de la variable.

Ejemplo clásico 1) – variable de shell sin trailing whitespace

 TIME=10 # WRONG: no such variable called 'TIMEsecs' echo "Time taken = $TIMEsecs" # What we want is $TIME followed by "secs" with no whitespace between the two. echo "Time taken = ${TIME}secs" 

Ejemplo 2)

 # WRONG CLASSPATH=hibernate-$LATESTVERSION_src.zip:hibernate_$LATEST_VERSION.jar 

(La respuesta de Fred ya lo dice pero su ejemplo es demasiado abstracto)

Siguiendo la sugerencia de SierraX y Peter sobre la manipulación de texto, los corchetes {} se usan para pasar una variable a un comando, por ejemplo:

Digamos que tiene un archivo sposi.txt que contiene la primera línea de una novela famosa italiana:

 > sposi="somewhere/myfolder/sposi.txt" > cat $sposi 

Ouput: quel ramo del lago di como che volge a mezzogiorno

Ahora crea dos variables:

 # Search the 2nd word found in the file that "sposi" variable points to > word=$(cat $sposi | cut -d " " -f 2) # This variable will replace the word > new_word="filone" 

Ahora sustituya la palabra contenido variable por la de new_word , dentro del archivo sposi.txt

 > sed -i "s/${word}/${new_word}/g" $sposi > cat $sposi 

Ouput: quel filone del lago di como che volge a mezzogiorno

La palabra “ramo” ha sido reemplazada.