
Em um script de shell, se eu definir uma variável como FOO=25
, há alguma diferença entre referenciá-la como $FOO$
e ${FOO}$
?
Responder1
Na maioria das situações, ambos $var
e ${var}
são iguais. (Observe que você não deve usar a $
no final!)
Um exemplo em que você precisa de chaves é quando precisa colocar uma variável em uma string contínua.
Exemplo:
var=hel
echo ${var}lo
irá produzir hello
.
Responder2
Para responder à sua pergunta principal, ${foo}
chama-se"expansão de parâmetros". Para ser mais preciso, o $
próprio inicia a expansão dos parâmetros, na { }
verdade são opcionais de acordo coma especificação POSIX, 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 os acima ou quando você está fazendomanipulação de cordas, eles são completamente equivalentes.
No entanto, você realmente não deve usar nenhum deles. A regra geral é que, com muito poucas exceções, você devesempreuse "$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 mais tarde). Você certamente não quer $foo$
. A final $
é irrelevante:
$ foo="bar"
$ echo "$foo$"
bar$
Portanto, embora variáveis sem aspas às vezes sejam aceitáveis:
$ echo $foo
bar
Geralmente não são e devem ser 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
or ${foo}
, o shell irádividiro valor salvo na variável no espaço em branco (isso pode ser alterado definindo a IFS
variável para outra coisa) em uma lista e então, cada elemento da lista é tratado como umglobopadrão e expandido em quaisquer arquivos ou diretórios correspondentes. Isto é conhecido comodividir+globooperador. 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 string, o shell informa que foo *
existe um arquivo chamado. Porém, se citarmos 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
embora.
Então, primeira regra:sempre cite suas variáveis.Você pode usar "$foo"
ou "${foo}"
mas citá-lo de qualquer maneira. Para mais detalhes sobre como usar variáveis com segurança, dê uma olhada nestas postagens: