foo=$bar
é seguro porque é uma atribuição , e uma atribuição a uma variável escalar, usando a sintaxe de atribuição escalar. É um contexto escalar , somente um valor pode ser armazenado em $var
, não faria sentido dividir ou glob $bar
. Se a expansão resultasse em várias palavras, o shell precisaria de alguma forma combiná-las novamente para poder armazená-las como uma string em $foo
.
É diferente quando você usa:
foo=($bar)
Onde você está atribuindo a uma variável de matriz. Existe um contexto de lista. Você está atribuindo um número de palavras aos elementos da matriz. split + glob ocorre.
Tenha também cuidado com a natureza dupla de coisas como export
/ local
/ typeset
/ declare
/ readonly
em algumas conchas (explicado em mais detalhes em Citações são necessárias para atribuição de variável local? )
Você notará que:
foo=$bar
é analisado como uma atribuição enquanto
"foo"=$bar
é apenas uma tentativa de executar o comando foo=content_of_bar
(onde o conteúdo da barra está sujeito a split + glob).
Em shells em que export
(e outros local
/ typeset
...) é tanto uma palavra-chave quanto uma versão interna (ksh, bash e versões recentes do zsh), em:
export foo=$bar
export
é reconhecido como uma palavra-chave e foo=$bar
como uma atribuição, portanto $bar
não está sujeito a divisão + glob. Mas é preciso pouco para que export
pare de ser reconhecido como uma palavra-chave . Nesse caso, ele é tratado apenas como um comando simples e split + glob acontece como em qualquer argumento para qualquer outro comando.
E mesmo nos casos em que export
é visto como uma palavra-chave, se os argumentos não se parecem com atribuições de variáveis (como no "foo"=$bar
acima), eles são tratados como argumentos normais e sujeitos a divisão + glob novamente.