Powiedzmy, że loguję się do powłoki w systemie uniksowym i zaczynam odsuwać polecenia. Początkowo zaczynam od katalogu domowego mojego użytkownika ~
. Mógłbym stamtąd cd
przejść do katalogu Documents
.
Polecenie zmiany katalogu roboczego jest bardzo proste intuicyjnie do zrozumienia: węzeł nadrzędny ma listę węzłów podrzędnych, do których może uzyskać dostęp, i prawdopodobnie używa (zoptymalizowanego) wariantu wyszukiwania w celu zlokalizowania istnienia węzła podrzędnego za pomocą wpisz nazwę użytkownika, a katalog roboczy zostanie „zmieniony”, aby dopasować to - popraw mnie, jeśli się mylę. Może być nawet prostsze, że powłoka po prostu „naiwnie” próbuje uzyskać dostęp do katalogu dokładnie zgodnie z życzeniem użytkownika, a gdy system plików zwraca pewien rodzaj błędu, powłoka odpowiednio wyświetla odpowiedź.
Interesuje mnie jednak to, jak działa ten sam proces, gdy przeglądam katalog, tzn. Do rodzica lub rodzica rodzica.
Biorąc pod uwagę moją nieznaną, prawdopodobnie „ślepą” lokalizację Documents
, jednego z możliwie wielu katalogów w całym drzewie systemu plików o tej nazwie, w jaki sposób Unix określa, gdzie powinienem być umieszczony dalej? Czy zawiera odniesienie pwd
i bada to? Jeśli tak, w jaki sposób pwd
śledzi bieżący stan nawigacji?
źródło
Odpowiedzi:
Inne odpowiedzi są uproszczeniami, z których każda przedstawia tylko fragmenty historii i są błędne w kilku punktach.
Istnieją dwa sposoby śledzenia katalogu roboczego:
chdir()
ifchdir()
, drugie przezchroot()
. Można je zobaczyć pośrednio w/proc
systemach operacyjnych Linux lub za pomocąfstat
polecenia na FreeBSD i tym podobnych:Kiedy działa rozpoznawanie nazw ścieżek, zaczyna się od jednego lub drugiego z tych przywoływanych vnodes, w zależności od tego, czy ścieżka jest względna czy bezwzględna. (Istnieje rodzina
…at()
wywołań systemowych, które umożliwiają rozpoznawanie nazw ścieżek rozpoczynające się od vnode, do którego odwołuje się deskryptor pliku otwartego (katalogu) jako trzecia opcja).W mikrojądrach Unices struktura danych znajduje się w przestrzeni aplikacji, ale zasada utrzymywania otwartych odniesień do tych katalogów pozostaje taka sama.
chdir()
.Jeśli ktoś zmieni się na względną nazwę ścieżki, manipuluje ciągiem, aby dodać tę nazwę. Jeśli ktoś zmieni bezwzględną nazwę ścieżki, zastępuje ciąg nową nazwą. W obu przypadkach dostosowuje ciąg do usunięcia
.
i..
komponentów oraz do ścigania dowiązań symbolicznych, zastępując je nazwami połączonymi z nimi. ( Oto przykładowy kod powłoki Z. )Nazwa w wewnętrznej zmiennej łańcucha jest śledzona przez zmienną powłoki o nazwie
PWD
(lubcwd
w powłokach C). Jest to konwencjonalnie eksportowane jako zmienna środowiskowa (o nazwiePWD
) do programów spawnowanych przez powłokę.Te dwie metody śledzenia rzeczy są ujawniane przez
-P
i-L
opcje docd
ipwd
powłoki wbudowanych komend i różnicami między muszli wbudowanychpwd
poleceń i zarówno/bin/pwd
polecenia i wbudowanychpwd
poleceń rzeczy jak (między innymi) VIM i NeoVIM.Jak widać: uzyskanie „logicznego” katalogu roboczego polega na spojrzeniu na
PWD
zmienną powłoki (lub zmienną środowiskową, jeśli nie jest to program powłoki); podczas gdy uzyskanie „fizycznego” katalogu roboczego jest kwestią wywołaniagetcwd()
funkcji biblioteki.Działanie
/bin/pwd
programu, gdy-L
używana jest opcja, jest nieco subtelne. Nie może ufać wartościPWD
odziedziczonej zmiennej środowiskowej. W końcu nie musiała być wywoływana przez powłokę, a interweniujące programy mogły nie wdrożyć mechanizmu powłoki polegającego na tym, żePWD
zmienna środowiskowa zawsze śledzi nazwę katalogu roboczego. Albo ktoś może zrobić to, co właśnie tam zrobiłem.Więc to, co robi (jak mówi standard POSIX), sprawdza, czy nazwa podana w
PWD
daje to samo co nazwa.
, co można zobaczyć za pomocą śledzenia wywołania systemowego:Jak widać: wywołuje tylko
getcwd()
wtedy, gdy wykryje niezgodność; i można go oszukać, ustawiającPWD
ciąg znaków, który rzeczywiście nazywa ten sam katalog, ale inną drogą.Funkcja
getcwd()
biblioteczna jest odrębnym przedmiotem. Ale aby to zrobić:..
katalogu. Zatrzymał się, gdy osiągnął pętlę, w której..
był taki sam jak katalog roboczy, lub gdy wystąpił błąd podczas próby otwarcia następnego..
. To byłoby dużo wywołań systemowych pod przykryciem.Zauważ jednak, że nawet w FreeBSD i innych systemach operacyjnych jądro nie śledzi łańcucha roboczego za pomocą łańcucha.
Nawigacja do
..
jest znowu osobnym tematem. Kolejna zasada: chociaż katalogi konwencjonalnie (choć, jak już wspomniano, nie jest to wymagane) zawierają rzeczywistą..
strukturę danych katalogu na dysku, jądro śledzi katalog macierzysty każdego vnode katalogu i może w ten sposób nawigować do..
vnode dowolnego katalog roboczy. Jest to nieco skomplikowane przez punkt montowania i zmienione mechanizmy rootowania, które są poza zakresem tej odpowiedzi.Na bok
Windows NT faktycznie robi podobne rzeczy. Istnieje jeden katalog roboczy na proces, ustawiony przez
SetCurrentDirectory()
wywołanie API i śledzony na proces przez jądro za pomocą (wewnętrznego) dojścia do otwartego pliku do tego katalogu; i istnieje zestaw zmiennych środowiskowych, które programy Win32 (nie tylko interpreter poleceń, ale wszystkie programy Win32) używają do śledzenia nazw wielu działających katalogów (jednego na dysk), dołączając je lub zastępując przy każdej zmianie katalogu.Konwencjonalnie, w przeciwieństwie do systemów operacyjnych Unix i Linux, programy Win32 nie wyświetlają tych zmiennych środowiskowych użytkownikom. Czasem można je zobaczyć w podsystemach uniksopodobnych działających w systemie Windows NT, a także przy użyciu poleceń interpretera
SET
poleceń w określony sposób.Dalsza lektura
pwd
” . Podstawowa specyfikacja grupy otwartej Wydanie 7. IEEE 1003.1: 2008. Grupa otwarta. 2016 r.źródło
..
w kontekście Plan9,.
i..
komponentów oraz do ścigania dowiązań symbolicznych, zastępując je nazwami połączonymi z nimi. … Nazwa w wewnętrznej zmiennej łańcucha jest śledzona przez zmienną powłoki o nazwiePWD
… ”(wyróżnienie dodane). … (Ciąg dalszy)PWD
=…/b
pocd b
poleceniu, mimo żeb
jest dowiązaniem symbolicznym doa
- więc powłoka nie „ściga”a -> b
łącza. Czy popełniłeś błąd, czy też źle przeczytałem?CHASE_LINKS
.Jądro nie śledzi nazw katalogów lub plików; plik lub katalog jest reprezentowany w jądrze przez parę węzłów i urządzeń. Wywołania systemowe, takie jak
chdir()
,open()
itp wziąć ścieżkę jako parametr, który może być bezwzględne (np/etc/passwd
) lub w stosunku do bieżącego katalogu (przykłady:Documents
,..
). Po uruchomieniu procesuchdir("Documents")
wyszukiwanie odbywa sięDocuments
w bieżącym katalogu roboczym, a katalog roboczy procesu jest aktualizowany w celu odniesienia do tego katalogu. Z punktu widzenia jądra w nazwie „..” nie ma nic specjalnego, to tylko konwencja w systemie plików, która..
odnosi się do katalogu nadrzędnego.Ta
getcwd()
funkcja nie jest wywołaniem systemowym, ale funkcją biblioteki, która musi dotrzeć do katalogu głównego, rejestrując po drodze nazwy komponentów ścieżki.źródło
Co ciekawe, tradycyjnie
cd ..
jest znacznie prostsze niżpwd
. Nazwy katalogów..
są umieszczane jawnie w systemie plików. System śledzi urządzenie / i-węzeł bieżącego katalogu,cd ..
a ściślej mówiąc, wywołanie systemowe wymagachdir("..")
jedynie wyszukania nazwy „..” w pliku należącym do i-węzła bieżącego katalogu i zmiany urządzenia / i-węzła bieżącego katalogu na wartość tam znaleziona.pwd
(dokładniej/bin/pwd
) podąża..
kolejno za linkami i odczytuje odpowiednie katalogi, aż do znalezienia i-węzła, z którego pochodzi, zestawiając listę tych nazw w odwrotnej kolejności, aż dotrze do katalogu głównego (zwłaszcza nie zawierającego..
wpisu).To jest pierwotne podstawowe zachowanie niskiego poziomu. Rzeczywiste polecenia powłoki
pwd
opierają się na różnych technikach buforowania bieżącej nazwy ścieżki. Ale w istocie znany jest tylko jego i-węzeł. Oznacza to, że po użyciu dowiązań symbolicznych do nawigacji w katalogach bieżące nazwy katalogów roboczych bieżącej powłoki i systemu/bin/pwd
mogą się różnić.źródło