Quando precisamos de chaves ao redor de variables ​​de shell?

Em scripts de shell, quando usamos {} ao expandir variables?

Por exemplo, eu vi o seguinte:

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

Existe uma diferença significativa ou é apenas um estilo? É um preferido em detrimento do outro?

Neste exemplo em particular, não faz diferença. No entanto, o {} em ${} é útil se você quiser expandir a variável foo na string

 "${foo}bar" 

já que "$foobar" seria expandido para foobar .

Chaves curvas também são incondicionalmente necessárias quando:

  • expandindo elementos de matriz, como em ${array[42]}
  • usando operações de expansão de parâmetro, como em ${filename%.*} (remove extension)
  • expandindo parâmetros posicionais além de 9: "$8 $9 ${10} ${11}"

Fazer isso em todos os lugares, em vez de apenas em casos potencialmente ambíguos, pode ser considerado uma boa prática de programação. Isso é para consistência e para evitar surpresas como $foo_$bar.jpg , onde não é visualmente óbvio que o sublinhado se torne parte do nome da variável.

As variables ​​são declaradas e atribuídas sem $ e sem {} . Você tem que usar

 var=10 

atribuir. Para ler a variável (em outras palavras, ‘expandir’ a variável), você deve 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. 

Isso me confundiu às vezes – em outras linguagens nos referimos à variável da mesma maneira, independentemente de estar à esquerda ou à direita de uma atribuição. Mas o shell-scripting é diferente, $var=10 não faz o que você acha que faz!

Você usa {} para agrupar. As chaves são necessárias para excluir os elementos da matriz. Exemplo:

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

Você também pode fazer alguma manipulação de texto dentro das chaves:

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

Resultado:

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

ou

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

Resultado:

 This_is_a_string 

Você está certo em “variables ​​regulares” não são necessários … Mas é mais útil para a debugging e ler um script.

O final do nome da variável é geralmente representado por um espaço ou nova linha. Mas e se não quisermos um espaço ou uma nova linha depois de imprimir o valor da variável? As chaves informam o interpretador de shell onde está o final do nome da variável.

Exemplo Clássico 1) – variável de shell sem espaço em branco à direita

 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" 

Exemplo 2)

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

(A resposta de Fred já diz isso, mas seu exemplo é um pouco abstrato demais)

Seguindo a sugestão do SierraX e Peter sobre manipulação de texto, chaves {} são usadas para passar uma variável para um comando, por exemplo:

Digamos que você tenha um arquivo sposi.txt contendo a primeira linha de um romance conhecido por weel italiano:

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

Acima de tudo: quel ramo del lago di como che volge a mezzogiorno

Agora crie duas 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" 

Agora substitua o conteúdo da variável word pelo de new_word , dentro do arquivo sposi.txt

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

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

A palavra “ramo” foi substituída.