Wiem, że prawdopodobnie o to wcześniej pytano, ale nie mogłem tego znaleźć w Google.
Dany
- Jądro Linux
- Brak konfiguracji zmieniających $ HOME
- grzmotnąć
Będzie ~ == $HOME
prawda
bash
shell
environment-variables
home
PythonNut
źródło
źródło
~
będzie to odpowiednik$HOME
w dowolnym środowisku POSIX; ale mogę się mylić.echo "~"
iecho "$HOME"
.~
ani$HOME
. : P~
”). W każdym razie, coś, aby pamiętać, dla zwykłego czytelnika, podobnie jak ja.Odpowiedzi:
Ważne jest, aby zrozumieć, że
~
rozszerzenie jest cechą powłoki (niektórych powłok), nie jest magiczną postacią, niż oznacza katalog domowy, gdziekolwiek jest używany.Jest rozszerzany (przez powłokę, która jest aplikacją służącą do interpretacji wiersza poleceń), podobnie jak
$var
jest rozszerzany do jego wartości w pewnych warunkach, gdy jest używany w linii poleceń powłoki przed wykonaniem polecenia.Ta funkcja pojawiła się po raz pierwszy w powłoce C pod koniec lat siedemdziesiątych (powłoka Bourne'a nie miała jej, podobnie jak jej poprzedniczka - powłoka Thompson), została później dodana do powłoki Korn (nowsza powłoka zbudowana na powłoce Bourne'a w 80s). Ostatecznie został ustandaryzowany przez POSIX i jest teraz dostępny w większości powłok, w tym takich jak non-POSIX
fish
.Ponieważ jest tak szeroko stosowany w powłokach, niektóre aplikacje inne niż powłoki również rozpoznają go jako oznaczający katalog domowy. Tak jest w przypadku wielu zastosowań w swoich plikach konfiguracyjnych lub ich własnej linii poleceń (
mutt
,slrn
,vim
...).bash
konkretnie (która jest powłoką projektu GNU i szeroko stosowana w wielu systemach operacyjnych opartych na Linuksie), gdy jest wywoływana jakosh
, przeważnie przestrzega reguł POSIX dotyczących~
ekspansji, aw obszarach nieokreślonych przez POSIX zachowuje się głównie jak powłoka Korna (z który jest częściowym klonem).Chociaż
$var
jest rozwijany w większości miejsc (z wyjątkiem pojedynczych cudzysłowów),~
ekspansja, będąca refleksją, jest rozwijana tylko w kilku konkretnych warunkach.Jest rozwijany, gdy sam argument w kontekstach list, w kontekstach, w których oczekiwany jest ciąg znaków.
Oto kilka przykładów jego rozszerzenia
bash
:cmd arg ~ other arg
var=~
var=x:~:x
(wymagane przez POSIX, używanego dla zmiennych podobaPATH
,MANPATH
...)for i in ~
[[ ~ = text ]]
[[ text = ~ ]]
(rozszerzenie~
jest traktowane jako wzór w AT&T,ksh
ale niebash
od 4.0).case ~ in ~) ...
${var#~}
(choć nie w innych powłokach)cmd foo=~
(choć nie przy wywołaniu jakosh
i tylko wtedy, gdy to, co znajduje się po lewej stronie=
ma kształt niecytowanejbash
nazwy zmiennej)cmd ~/x
(oczywiście wymagane przez POSIX)cmd ~:x
(ale niex:~:x
lubx-~-x
)a[~]=foo; echo "${a[~]} $((a[~]))"
(nie w niektórych innych powłokach)Oto kilka przykładów, w których nie jest rozwinięty:
echo "~" '~'
echo ~@ ~~
(zauważ również, że~u
ma on na celu rozszerzenie do katalogu domowego użytkownikau
).echo @~
(( HOME == ~ ))
,$(( var + ~ ))
extglob
:case $var in @(~|other))...
(choćcase $var in ~|other)
jest OK)../configure --prefix=~
(ponieważ--prefix
nie jest prawidłową nazwą zmiennej)cmd "foo"=~
(wbash
, ze względu na cytaty).sh
:export "foo"=~
,env JAVA_HOME=~ cmd
...Jeśli chodzi o to, do czego się rozwija:
~
sam rozwija się do zawartościHOME
zmiennej lub, gdy nie jest ustawiona, do katalogu domowego bieżącego użytkownika w bazie danych kont (jako rozszerzenie, ponieważ POSIX pozostawia to zachowanie niezdefiniowane).Należy zauważyć, że w ksh88 i
bash
wersjach wcześniejszych niż 4.0 ekspansja tyldy przeszła globbing (generowanie nazw plików) w kontekście list:Nie powinno to stanowić problemu w zwykłych przypadkach.
Pamiętaj, że ponieważ jest rozwinięty, to samo ostrzeżenie ma zastosowanie do innych form rozszerzeń.
Nie działa, jeśli
$HOME
zaczyna się od-
lub zawiera..
składniki. Tak więc, chociaż jest bardzo mało prawdopodobne, aby kiedykolwiek coś zmienić, ściśle mówiąc, należy napisać:Lub nawet:
(w celu pokrycia wartości
$HOME
podobnych-
,+2
...) lub po prostu:(jak
cd
zabierze Cię do katalogu domowego bez żadnych argumentów)Inne pociski mają bardziej zaawansowane
~
rozszerzenia. Na przykład wzsh
:~4
,~-
,~-2
(W realizacji) wykorzystywane do rozszerzenia katalogi w stosie Directory (miejsc, które jużcd
się wcześniej).~something
rozbudowy.źródło
W dowolnej wersji Bash na dowolnym systemie, tak .
~
jako termin definiowany jest jako rozszerzenie do:więc zawsze będzie taki sam, jak
$HOME
dla bieżącej powłoki. Istnieje kilka innych rozszerzeń tyldy, na przykład~user
dlauser
katalogu domowego, ale pojedynczy sam w cudzysłowie~
zawsze będzie się rozwijał"$HOME"
.Należy zauważyć, że zachowanie od
~
i$HOME
może być różny w niektórych przypadkach: w szczególności, jeśli$HOME
zawiera spacje (lub inne IFS znaków), a następnie$HOME
(cytowane) wzrośnie do kilku słów, a~
to zawsze jedno słowo.~
rozwija się równorzędnie do"$HOME"
(cytowany).W odniesieniu do twojego konkretnego pytania:
jest zawsze prawdziwe, ponieważ
[[
eliminuje dzielenie słów.[[ ~ == $HOME ]
może nie być, jeśliHOME
zawiera znaki pasujące do wzorca , ale[[ ~ == "$HOME" ]]
(tj. cytowane"$HOME"
) jest zawsze prawdziwe. Używanie go w nawiasach pojedynczych może być błędem składniowym dla wartościHOME
zawierających spacje lub znaki specjalne. Dla każdej sensownej konfiguracji katalogu domowego~
i"$HOME"
są takie same i porównać jako równe.Stéphane Chazelas zauważył przypadek w komentarzach gdzie
~
i$HOME
podaje różne wartości: jeśli tyunset HOME
, to kiedy użyjesz~
Bash zadzwoni,getpwuid
aby odczytać wartość z bazy danych haseł. Ten przypadek jest wykluczony z powodu braku zmiany konfiguracji$HOME
, ale wspomnę o tym tutaj dla kompletności.źródło
/bin/sh
może nie byćbash
. Nie jestem pewien, czysh
specyfikacja Posix mówi~
~
.~
nie było w skorupie Thomsona ani Bourne'a (które w swoim czasie były dostępne jako/bin/sh
). Nie ma go ani nierc
jest pochodną (gdzie jest używany do czegoś innego)bash
, jeśli nieHOME
jest ustawiony,~
rozwija się do katalogu domowego użytkownika z bazy danych passwd. Jest to przypadek, w którym~
może nie rozwinąć się do wartości$HOME
.bash
przed bash4 używał globowania po rozwinięciu tyldy (tryHOME='/*' bash -c 'echo /*'
). Zwróciłby więcHOME=/*; [ "$HOME" = ~ ]
tam błąd.get_current_user_info
, który wykorzystujegetpwuid
na wszystkich platformach, ale Tandem .