O que é importante entender é que ~ expansion é um recurso do shell (de alguns shells), não é um magic character que significa seu diretório home onde quer que seja usado.
Ele é expandido (pelo shell, que é um aplicativo usado para interpretar linhas de comando), como $var é expandido para seu valor sob algumas condições quando usado em uma linha de comando do shell antes do comando ser executado.
Esse recurso apareceu pela primeira vez no C-shell no final dos anos 1970 (o shell Bourne não o tinha, nem seu antecessor, o shell Thompson), foi posteriormente adicionado ao shell Korn (um shell mais novo construído sobre o Bourne shell nos anos 80). Ele acabou sendo padronizado pelo POSIX e agora está disponível na maioria dos shells, incluindo os que não são POSIX, como fish .
Como ele é amplamente usado em shells, alguns aplicativos que não são shell também o reconhecem como significando o diretório inicial. Esse é o caso de muitos aplicativos em seus arquivos de configuração ou na linha de comando própria ( mutt , slrn , vim ...).
bash especificamente (que é o shell do projeto GNU e amplamente usado em muitos sistemas operacionais baseados em Linux), quando invocado como sh , segue principalmente o Regras POSIX sobre a expansão ~ e, em áreas não especificadas pelo POSIX, se comportam principalmente como o shell Korn (do qual é parte o clone ), embora veja o bug mencionado abaixo.
Enquanto $var é expandido na maioria dos locais (exceto entre aspas simples), ~ expansão, sendo uma reflexão tardia é expandida apenas em algumas condições específicas.
Ele é expandido quando em seu próprio argumento em contextos de lista, em contextos em que uma string é esperada.
Aqui estão alguns exemplos de onde ele foi expandido em bash :
-
cmd arg ~ other arg -
var=~ -
var=x:~:x(requerido pelo POSIX, usado para variáveis comoPATH,MANPATH...) -
for i in ~ -
[[ ~ = text ]] -
[[ text = ~ ]](~sendo considerado como padrão emksh, mas nãobash). -
case ~ in ~) ... -
${var#~}(embora não em algumas outras shells) -
cmd foo=~(embora não quando invocado comosh, e somente quando o que está à esquerda do=tenha o formato de um nome de variávelbashsem aspas) -
cmd ~/x(requerido pelo POSIX obviamente) -
cmd ~:x(mas nãox:~:xoux-~-x) -
a[~]=foo; echo "${a[~]} $((a[~]))"(não em algumas outras shells)
Aqui estão alguns exemplos em que não estão expandidos:
-
echo "~" '~' -
echo ~@ ~~(observe também que~use destina a expandir para o diretório inicial do usuáriou). -
echo @~ -
(( HOME == ~ )),$(( var + ~ )) - com
extglob:case $var in @(~|other))...(emboracase $var in ~|other)esteja OK). -
./configure --prefix=~(como--prefixnão é um nome de variável válido) -
cmd "foo"=~(embash, por causa das aspas). - quando chamado como
sh:export "foo"=~,env JAVA_HOME=~ cmd...
Quanto ao que é expandido para: ~ sozinho se expande para o conteúdo da variável HOME , ou quando não está definido, para o diretório inicial do usuário atual no banco de dados da conta (como uma extensão desde POSIX deixa esse comportamento indefinido).
Deve-se observar que em bash versões anteriores à 4.0, a expansão de til foi submetida a globbing (geração de nome de arquivo) em contextos de lista:
$ bash -c 'echo "$HOME"'
/home/***stephane***
$ bash -c 'echo ~'
/home/***stephane*** /home/stephane
$ bash -c 'echo "~"'
~
Isso não deve ser um problema em casos comuns.
Observe que, como ele é expandido, o mesmo aviso se aplica a outras formas de expansão.
cd ~
Não funciona se $HOME começar com - ou contiver .. componentes. Então, mesmo que seja improvável que faça alguma diferença, estritamente falando, deve-se escrever:
cd -P -- ~
Ou até mesmo:
case ~ in
(/*) cd -P ~;;
(*) d=~; cd -P "./$d";;
esac
(para cobrir valores de $HOME como - , +2 ...) ou simplesmente:
cd
(como cd leva você ao seu diretório pessoal sem nenhum argumento)
Outras camadas têm expansões ~ mais avançadas. Por exemplo, em zsh , temos:
-
~4,~-,~-2(com conclusão) usado para expandir os diretórios na sua pilha de diretórios (os lugares com os quais você temcd). -
diretórios nomeados dinâmicos . Você pode definir seu próprio mecanismo para decidir como o
~somethingestá sendo expandido.