Existem vários aspectos para esta questão, conforme solicitado. Em primeiro lugar, os efeitos de uma atribuição entre aspas podem diferir da mesma declaração de atribuição sem citações por dois motivos:
-
Se a atribuição contiver símbolos de sintaxe (como ;<> ou espaço em branco) , as cotações servirão para incluí-las, enquanto a instrução de atribuição sem aspas delimitará no token.
-
Em bash e alguns outros shells, os tokens () são casos especiais em que var=(...) serve para indicar uma atribuição de matriz, embora a mesma construção seja um erro de sintaxe sem aspas em um shell POSIX que não suporta a extensão da matriz.
( spc= sc=; echo "<$spc>:<$sc>"
spc=' ' sc=\;; echo "<$spc>:<$sc>"
)
<>:<>
< >:<;>
-
Se a atribuição contiver tokens de expansão, as cotações podem servir para impedir que a expansão ocorra, como de outra forma aconteceria sem elas.
- Quaisquer tokens contidos dentro de uma expansão não se aplicam, pois o conteúdo da expansão é literalmente passado da expansão para a variável designada.
-
O " de aspas duplas não atende a esse propósito para $ denotadas expansões de shell e, portanto, é geralmente estranho em uma instrução de atribuição, embora possa ser usado para conter $ denotadas expansões e outros tokens de shell em um contexto citado.
( spc=\ sc=";"
tkns=$(printf "(<\n\'\t)>|")$spc$sc\"
names=tkns$spc$"sc$spc$"spc
printf ::$%s::\n "$names" "$tkns"
)
::$tkns $sc $spc::
::$(<
\' )>| ;"::
Os tokens de shell são caracteres muito especiais para o shell - eles são os caracteres que separam os comandos uns dos outros e as palavras de comando dos argumentos de comando. Eles são os caracteres que delimitam / concatenam palavras de shell. Tokens de shell são os caracteres que o sintetizador da shell (ou lexer ) estará procurando e atuando conforme lê em um comando antes de qualquer o shell tem a chance de considerar expandir qualquer parte dele.
Mas há outros caracteres que são quase especiais para o shell. Esses são caracteres que afetam as expansões do shell, como aquelas contidas no valor do parâmetro $IFS do shell, e metacaracteres de expansão de nome de arquivo como ?[* e - como observado em sua pergunta - o ~ tilde.
Com exceção do ~ til em casos especiais, esses caracteres não têm relação com instruções de atribuição - o contexto atribuição (em oposição ao contexto lista ) é imune a ambas as expansões $IFS splitting e filename. E assim, as expansões que ocorrem dentro de uma atribuição de variáveis não precisam ser protegidas para valores literais da maneira que você deveria em uma lista de comandos.
E os seguintes trabalhos ...
(meta=*?; meta=[$meta; echo "$meta")
[*?
O ~ tilde, no entanto, é um tipo especial de expansão de shell. Sua expansão é tratada como um shell alias em que seu conteúdo é sempre expandido literalmente. ~ til e alias expansões - como as mais típicas $ sinal de dólar denotam expansões no contexto atribuição - são sempre imunes a $IFS e nome do arquivo expansões. Eles diferem, entretanto, em que o ~ tilde quase sempre é expandido como argumento, e um shell alias não pode ser expandido nesse contexto a menos que ele siga imediatamente outro alias que foi expandido e cujo valor termina com um < espaço >.
Uma expansão ~ tilde não ocorrerá entre aspas de qualquer tipo e, por falar nisso, não ocorrerá a menos que seja adequadamente delimitada por todos os lados, ou a menos que seu contexto à direita nomeie um usuário do sistema e o shell pode confirmar corretamente este fato.
E então ...
~some_user
... expandirá para o diretório home do usuário some_user se o shell puder confirmar que esse usuário existe ou não expandirá.
Para delimitar adequadamente uma expansão ~ tilde você pode usar qualquer um dos tokens de shell já mencionados exceto as aspas mais um / no lado direito em uma lista contexto, ou, em um contexto atribuição , / ou : no lado direito ou, à esquerda, o primeiro = no comando de atribuição ou : em qualquer outro lugar.
Quando não houver nenhum contexto à direita, e o ~ til for adequadamente delimitado, o ~ tilde será expandido para o valor atual da variável $HOME da shell. Essa distinção é muitas vezes erroneamente ignorada quando se discute a expansão ~ til. O diretório inicial de um usuário e o valor em $HOME não precisam ser os mesmos, pois a variável de shell $HOME pode ser reatribuída ou unset a qualquer momento, como qualquer outro. De fato, quando $HOME é unset , POSIX deixa o comportamento de uma expansão% de% til% solitária, não especificada , embora ~ , por exemplo, tente uma pesquisa com o sistema para o diretório inicial do usuário atual.
Por exemplo:
HOME="
:~"::~//~ bash -c '
printf "\t<%s>" ~/ ~mikeserv/
HOME=; echo
printf "\t<%s>" ~/ ~mikeserv/
unset HOME; echo
printf "\t<%s>" ~/ ~mikeserv/
'
<
:~::/home/mikeserv//~/> </home/mikeserv/>
</> </home/mikeserv/>
</home/mikeserv/> </home/mikeserv/>