Diferença entre $ HOME e ~

31

$HOMEe ~geralmente se referem à mesma coisa. Ou seja, eles são o caminho para o diretório "home do usuário", que tem a forma geral "/ home / userName".

Quando, se alguma vez, eles não se referem ao mesmo diretório?

H2ONaCl
fonte
11
O ~shell é dependente, enquanto $ HOME não.
Kulfy 29/09
Muito unix.stackexchange.com/a/400715/85039
Sergiy Kolodyazhnyy

Respostas:

45

Ambos $HOMEe ~apontam para a mesma pasta, pasta pessoal do usuário atual, mas ambos são coisas muito diferentes.

  • $HOMEé uma variável de ambiente , definida para conter a pasta inicial do usuário atual.
  • ~é um símbolo de expansão do shell , ou seja, um dos símbolos processados ​​antes do comando real ser executado. ~sozinho expande para o valor de $ HOME. ~nemoexpande para o diretório inicial do usuário nemo. Um símbolo de expansão do shell é um caractere (ou par de caracteres) que é processado / interpretado pelo shell para criar o comando real. Outro exemplo de símbolo de expansão de shell *é usado para expandir nomes de arquivos.
vanádio
fonte
1
~expande para $ HOME ou% APPDATA% no Windows. Se eles não estiverem definidos, procurará o caminho "no banco de dados de senhas" (o que geralmente significa /etc/passwd, mas pode ser LDAP ou alguma outra fonte de dados). Cerca de 20 anos atrás, você poderia ter sido avisado de que o $ HOME talvez não estivesse definido em algumas máquinas, enquanto a ~garantia de expandir para algo.
Mirek Długosz
Essa diferença é notável em programas como o make, quando você precisa saber qual dos dois você precisa
D. Ben Knoble 29/09
3
@ MirekDługosz Pelo menos no git bash no Windows, ~expande para $HOME(igual a $HOMEPATH), não $APPDATA. E no cmd.exe, ~não se expande.
hyde
1
@vanadium HOMEé uma variável de ambiente (um conceito OS, em sh conchas por exemplo conjunto com exportou declare -x), não uma variável de shell (definição de que depende inteiramente de shell, mas em sh conchas é geralmente definido com foo=valueou com setou em alguns outros maneiras).
hyde
1
@hyde eu expressei isso errado. o bash verificará $ HOME, se não estiver definido, verificará% APPDATA%, mas apenas no Windows; se não estiver definido, procurará "o banco de dados de senhas". Veja git.savannah.gnu.org/cgit/bash.git/tree/lib/readline/…
Mirek Długosz em
17

Uma maneira de diferir é a forma como o shell Bash os converte quando colocados "entre aspas.

Se você usar echodesta maneira, sem aspas, ~e $HOMEterá o mesmo efeito:

$ echo ~
/home/elias
$ echo $HOME
/home/elias

No entanto, entre "aspas, o resultado difere:

$ echo "~"
~
$ echo "$HOME"
/home/elias
Elias
fonte
13

~só se expande como parte de um prefixo de til que, por definição, deve começar no início da palavra. Além disso, como fazia parte dos padrões de globbing, ~não funcionará entre aspas duplas. Portanto, "~"ou a~bresultará em um valor literal de ~preservação.

Um único ~(ou um ~seguido de a /) será expandido para a página inicial do usuário atual:

$ echo ~/.ssh
/home/user/.ssh

Um ~seguido por um nome de usuário será expandido para a pasta inicial desse usuário:

$ echo ~root/.ssh
/root/.ssh

A ~seguido de a +ou a -e um número opcional serão expandidos para elementos da pilha de diretórios :

$ cd /etc
$ echo ~+0
/etc

$HOMEé o equivalente a um único ~, que segue regras de sintaxe para variáveis. Por exemplo, ele se expande entre aspas duplas, pode ser desconfigurado e operandos de manipulação de string podem ser aplicados a ele.

Dmitry Grigoryev
fonte
3

Isso depende muito do que faz a expansão. No bash, ~é uma maneira conveniente de obter o diretório inicial sem acionar a expansão do arquivo ou a divisão de palavras, mesmo que não esteja entre aspas. Por exemplo:

$ HOME='/*'
$ echo $HOME
/bin /boot /dev /etc /home /lib /lib64 /media /mnt /opt /proc /root /run /sbin /srv /sys /tmp /usr /var
$ echo ~
/*

Ou:

$ HOME='/ a b'
$ printf "|%s|\n" $HOME ~
|/|
|a|
|b|
|/ a b|

Portanto, se você estiver lutando com aspas por algum motivo (nesse caso, você realmente deve repensar a coisa toda, é mais fácil lutar com porcos), ~pode ser mais conveniente.


Em outros lugares, em Python, por exemplo, ~e $HOMEprecisa ser expandido por diferentes funções . Alguns outros lugares permitem variáveis ​​e não permitem outras sintaxes de shell, como curingas ou expansão de til (por exemplo ~/.pam_environment, que possui uma sintaxe especial para expansão de variáveis). Outros lugares ainda permitem a expansão do til como uma exceção (por exemplo, systemd ), mas consultam o banco de dados passwd diretamente em vez de usar $HOME.

homeboy
fonte
Outra grande diferença, que você mostra aqui, mas não menciona, é que você pode alterar o valor de $HOME, mas não pode (diretamente) alterar o valor de ~.
Joe
Por isso, perguntei quando fazer $HOMEe ~não se referir à mesma coisa - normalmente, por padrão - e, em seguida, você atribui deliberadamente à variável de ambiente para fazê-la não se referir à mesma coisa. Esta é uma boa demonstração, mas desnecessariamente confusa.
H2ONaCl
1

É mais provável que $ HOME / funcione no padrão POSIX.2 Bourne / bin / sh, pois a expansão til é uma extensão encontrada no BSD csh tcsh GNU bash e outros.

Se você deseja gravar scripts portáteis no busybox, dash ou BSD sh, invista nas letras extras para não bater com ~ /: Esse arquivo ou diretório não existe em determinados sistemas.

Também acho $ HOME / mais legível.

Roman Czyborra
fonte
Em um script, a legibilidade e a visibilidade são importantes. Talvez seja por isso que meus scripts usam $HOMEe raramente usam ~. Meu antigo eu provavelmente sabia disso.
H2ONaCl