Różnica między $ HOME a ~

31

$HOMEi ~zwykle odnoszą się do tego samego. Oznacza to, że są ścieżką do katalogu „user home”, który ma ogólną postać „/ home / userName”.

Kiedy, jeśli w ogóle, nie odnoszą się one do tego samego katalogu?

H2ONaCl
źródło
11
Do ~znaczy powłoki zależne natomiast $ HOME nie jest.
Kulfy
Bardzo mocno powiązany unix.stackexchange.com/a/400715/85039
Sergiy Kolodyazhnyy

Odpowiedzi:

45

Zarówno $HOMEi ~punkt w tym samym folderze, w katalogu domowym użytkownika bieżącego, ale oba są bardzo różne rzeczy.

  • $HOMEjest zmienną środowiskową , która zawiera folder domowy bieżącego użytkownika.
  • ~jest symbolem rozszerzenia powłoki , tj. jednym z symboli przetwarzanych przed wykonaniem właściwego polecenia. ~sam rozwija się do wartości $ HOME. ~nemorozwija się do katalogu domowego użytkownika nemo. Symbol rozwinięcia powłoki to znak (lub para znaków), który jest przetwarzany / interpretowany przez powłokę w celu zbudowania rzeczywistego polecenia. Innym przykładem symbolu rozwinięcia powłoki *jest rozszerzenie nazw plików.
wanad
źródło
1
~rozwija się do $ HOME lub% APPDATA% w systemie Windows. Jeśli nie są zdefiniowane, szuka ścieżki w „bazie danych haseł” (co zwykle oznacza /etc/passwd, ale może to być LDAP lub inne źródło danych). Jakieś 20 lat temu mogłeś zostać ostrzeżony, że $ HOME może nie być ustawiony na niektórych komputerach, podczas gdy na pewno zostanie ~rozwinięty do czegoś.
Mirek Długosz
Ta różnica jest zauważalna w programach takich jak make, kiedy musisz wiedzieć, który z nich potrzebujesz
D. Ben Knoble,
3
@ MirekDługosz Przynajmniej na git bash w Windows, ~rozwija się do $HOME(równy $HOMEPATH), a nie $APPDATA. A na cmd.exe ~nie rozwija się.
hyde
1
@vanadium HOMEto zmienna środowiskowa (koncepcja systemu operacyjnego, w powłokach sh, na przykład ustawiona za pomocą exportlub declare -x), a nie zmienna powłoki (której definicja zależy całkowicie od powłoki, ale w powłokach sh jest zwykle ustawiana za pomocą foo=valuelub z setkilkoma innymi sposoby).
hyde
1
@hyde Wyraziłem to źle. bash sprawdzi $ HOME, jeśli nie jest ustawiony, sprawdzi% APPDATA%, ale tylko w systemie Windows; jeśli nie jest ustawiony, przeszuka „bazę danych haseł”. Zobacz git.savannah.gnu.org/cgit/bash.git/tree/lib/readline/…
Mirek Długosz
17

Różnią się między sobą tym, w jaki sposób powłoka Bash przekształca je, gdy są ujęte w "cudzysłów.

Jeśli używasz w echoten sposób, bez cudzysłowów, to ~i $HOMEmasz ten sam efekt:

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

Jednak "wokół znaków cudzysłowu wynik jest różny:

$ echo "~"
~
$ echo "$HOME"
/home/elias
Elias
źródło
13

~rozwija się tylko jako część przedrostka tyldy, który z definicji musi zaczynać się na początku słowa. Ponadto, ponieważ kiedyś był częścią wzorców globowania, ~nie będzie działał w cudzysłowie. Tak więc "~"lub a~bspowoduje zachowanie dosłownej wartości ~.

Pojedyncza ~(lub ~następująca po niej /) zostanie rozwinięta do domu bieżącego użytkownika:

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

~Następnie nazwę użytkownika wzrośnie do katalogu domowego danego użytkownika:

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

Po nich ~następuje a +lub a -i opcjonalny numer zostaną rozwinięte do elementów stosu katalogów :

$ cd /etc
$ echo ~+0
/etc

$HOMEjest odpowiednikiem pojedynczego ~, który zamiast tego przestrzega reguł składniowych dla zmiennych. Na przykład, rozwija się wewnątrz podwójnych cudzysłowów, można go rozbroić i można do niego zastosować operandy do manipulacji ciągami .

Dmitrij Grigoriew
źródło
3

Zależy to w dużej mierze od rozszerzenia. W bash ~jest wygodnym sposobem na uzyskanie katalogu domowego bez uruchamiania rozszerzenia nazwy pliku ani dzielenia słów, nawet jeśli nie jest cytowany. Na przykład:

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

Lub:

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

Więc jeśli zmagasz się z cytatami z jakiegoś powodu (w takim przypadku naprawdę powinieneś przemyśleć całość, łatwiej jest walczyć ze świniami), ~może być wygodniejsze.


Gdzie indziej, na przykład w Pythonie ~i $HOMEmuszą zostać rozszerzone o różne funkcje . Niektóre inne miejsca dopuszczają zmienne i nie pozwalają na inną składnię powłoki, taką jak symbole wieloznaczne lub interpretacja tyldy (np. ~/.pam_environment, Która ma specjalną składnię do interpretacji zmiennych). Jeszcze inne miejsca zezwalają na interpretację tyldy jako wyjątek (np. Systemd ), ale zamiast używać zapytania bezpośrednio do bazy danych passwd $HOME.

chłopak domowy
źródło
Kolejną dużą różnicą, którą tutaj pokazujesz, ale nie wspominając, jest to, że możesz zmienić wartość $HOME, ale nie możesz (bezpośrednio) zmienić wartości ~.
Joe
Zapytałem więc, kiedy $HOMEi ~nie odnoszą się do tej samej rzeczy - zwykle robią to domyślnie - a następnie celowo przypisujesz zmienną środowiskową, aby nie odnosiły się do tej samej rzeczy. To dobra demonstracja, ale niepotrzebnie myląca.
H2ONaCl
1

$ HOME / jest bardziej prawdopodobne, że będzie działać w standardowym POSIX.2 Bourne / bin / sh, ponieważ rozszerzenie tyldy jest rozszerzeniem występującym w BSD csh tcsh GNU bash i innych.

Jeśli chcesz pisać skrypty przenośne na busyboksie, desce rozdzielczej lub BSD sh, zainwestuj w dodatkowe litery, abyś nie zawiesił się przy ~ /: brak takiego pliku lub katalogu w niektórych systemach.

Uważam też, że $ HOME / jest bardziej czytelny.

Roman Czyborra
źródło
W skrypcie ważna jest czytelność i widoczność. Być może dlatego moje skrypty używają $HOMEi rzadko używają ~. Moje poprzednie ja prawdopodobnie to wiedziało.
H2ONaCl