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/>