Referenciando variáveis ​​em um script de shell

Referenciando variáveis ​​em um script de shell

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 $vare ${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, $fooe ${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 $fooou ${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 $fooor ${foo}, o shell irádividiro valor salvo na variável no espaço em branco (isso pode ser alterado definindo a IFSvariá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 fooe *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 rmem vez de echoembora.

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:

informação relacionada