Para responder à sua pergunta principal, ${foo}
é chamado de "expansão de parâmetro" . Para ser preciso, o $
inicia a expansão do parâmetro, os { }
são realmente opcionais de acordo com o POSIX especificação , mas pode ser útil para indicar o final do nome da variável:
$ foo="bar"
$ echo $fooBaz ## fails, no variable named $fooBaz exists
$ echo ${foo}Baz ## works, $foo is expanded and the string Baz is appended
barBaz
Basicamente, $foo
e ${foo}
são idênticos. Além de casos como o acima ou quando você está fazendo manipulação de string , eles são completamente equivalentes .
No entanto, você não deve usar nenhum deles. A regra básica é que, com pouquíssimas exceções, você deve sempre usar "$foo"
ou "${foo}"
e nunca $foo
ou ${foo}
. Você deve sempre citar suas variáveis para evitar invocar o operador split + glob (mais sobre isso depois). Você certamente não deseja $foo$
. O% final $
é irrelevante:
$ foo="bar"
$ echo "$foo$"
bar$
Assim, enquanto as variáveis sem aspas são às vezes OK:
$ echo $foo
bar
Eles geralmente não são e devem ser realmente evitados:
$ if [ -n $foo ]; then echo empty; else echo "not empty"; fi ## fails
empty
$ if [ -n "$foo" ]; then echo empty; else echo "not empty"; fi ## works
not empty
Observe que os colchetes também não ajudam aqui:
$ if [ -n ${foo} ]; then echo empty; else echo "not empty"; fi ## fails
empty
$ if [ -n "${foo}" ]; then echo empty; else echo "not empty"; fi ## works
not empty
Quando você usa $foo
ou ${foo}
, o shell divide o valor salvo na variável no espaço em branco (isso pode ser alterado definindo a variável IFS
para outra coisa) em uma lista e, em seguida, cada elemento da lista é tratado como um padrão glob e expandido em quaisquer arquivos ou diretórios correspondentes. Isso é conhecido como o operador split + glob . Para ilustrar, considere um diretório com dois arquivos:
$ ls -l
-rw-r--r-- 1 terdon terdon 0 Oct 9 18:16 file1
-rw-r--r-- 1 terdon terdon 0 Oct 9 18:16 file2
Agora, vamos definir uma variável para foo *
:
$ foo="foo *"
O que acontece se tentarmos verificar se existe um arquivo com esse nome?
$ if [ -e $foo ]; then echo "file exists"; else echo "no such file"; fi
file exists
A variável foi dividida em foo
e *
e, como *
é um curinga que corresponde a qualquer sequência, o shell informa que um arquivo chamado foo *
exxists. No entanto, se citá-lo corretamente, isso não acontece:
$ if [ -e "$foo" ]; then echo "file exists"; else echo "no such file"; fi
no such file
Esse foi um exemplo trivial para ilustrar o ponto. Imagine se eu tivesse usado rm
em vez de echo
.
Então, primeira regra: sempre cite suas variáveis. Você pode usar "$foo"
ou "${foo}"
, mas citar de qualquer forma. Para mais detalhes sobre o uso de variáveis com segurança, dê uma olhada nestes posts: