Jak stwierdzić, czy faktycznie jestem w lokalizacji dowiązania symbolicznego z wiersza poleceń?

33

Załóżmy, że mam folder:

cd /home/cpm135/public_html

i stworzyć dowiązanie symboliczne

ln -s /var/lib/class .

Później jestem w tym katalogu:

cd /home/cpm135/public_html/class

To pwdpowie mi, że jestem w środku/home/cpm135/public_html/class

Czy jest jakiś sposób, aby wiedzieć, że jestem „naprawdę” /var/lib/class? Dzięki

Oliver Williams
źródło
1
Niektóre muszle w rzeczywistości nie pozwalają ci znajdować się w dowiązaniu symbolicznym. Na przykład fishpowłoka automatycznie rozpoznaje dowiązanie symboliczne po przejściu cddo niego.
trysis,

Odpowiedzi:

56

W zależności od pwdkonfiguracji polecenia może domyślnie wyświetlać logiczny katalog roboczy (wyjście przez pwd -L), który pokazywałby lokalizację dowiązania symbolicznego, lub fizyczny katalog roboczy (wyjście przez pwd -P), który ignoruje dowiązanie symboliczne i pokazuje „prawdziwy” katalog.

Aby uzyskać pełne informacje, możesz to zrobić

file "$(pwd -L)"

Wewnątrz dowiązania symbolicznego nastąpi powrót

/path/of/symlink: symbolic link to /path/of/real/directory
Zanna
źródło
1
tak, -Pflaga była tym, czego potrzebowałem. Dzięki
Oliver Williams
6
Również odpowiedzieć na pytanie w tytule, wystarczy użyć test "$(pwd -L)" = "$(pwd -P)" && echo No symlinks(lub wymienić && echo No symlinksz || echo Symlinks).
CVn
1
To doskonale odpowiada na pytanie, bez potrzeby powtarzania. Jeśli pytanie brzmiałoby: „Jak wyświetlić komunikat, jeśli jestem w katalogu z dowiązaniem symbolicznym?”, Echo byłoby wymagane.
Arronical
file "$(pwd)"działa tylko wtedy, gdy dowiązanie symboliczne jest ostatnim składnikiem katalogu. Po wykryciu CD nie wykrywa dowiązania symbolicznego OP /home/cpm135/public_html/class/foo/bar. Nie znam niczego, co wyświetla informacje o wszystkich dowiązaniach symbolicznych w nazwie ścieżki, ale możesz także użyć realpath ., co moim zdaniem jest równoważnepwd -P
Peter Cordes
17

Zauważ, że pwdtak naprawdę jest to wbudowana powłoka. W zależności od powłoki i jej konfiguracji wyniki mogą ulec zmianie. Aby uzyskać bardziej przenośne rozwiązanie, powinieneś użyć /bin/pwd. Fragment ze strony podręcznika:

NAME
       pwd - print name of current/working directory

SYNOPSIS
       pwd [OPTION]...

DESCRIPTION
       Print the full filename of the current working directory.

       -L, --logical
              use PWD from environment, even if it contains symlinks

       -P, --physical
              avoid all symlinks

       --help display this help and exit

       --version
              output version information and exit

       If no option is specified, -P is assumed.

       NOTE:  your  shell  may  have  its  own  version of pwd, which usually supersedes the version described here.  Please refer to your shell's documentation for
       details about the options it supports.

Zasadniczo można rozwiązać pełną ścieżkę kanoniczną dowolnego pliku / katalogu, używając readlink -f. readlink -f .działa podobnie do pwd -P.

Gowtham
źródło
2
Chociaż nauczyłem się trudnej drogi, która readlink -fnie jest dostępna we wszystkich Uniksach (np. Niedostępna w OS-X)
abligh,
3

Naprawdę jesteś /home/cpm135/public_html/class- to jedyna poprawna odpowiedź na pytanie „jaki jest mój bieżący katalog roboczy”.

Kiedy odnosisz się do /var/lib/class... to tak naprawdę nie chodzi o to, gdzie jesteś, ale o to, jaką ścieżkę się tam dostałeś .

Po uruchomieniu /bin/pwdoblicza bieżący katalog roboczy, patrząc na. i .. katalogi (wymienione na górze ls -la), określające, który katalog w .. pasuje do. a następnie pracując wstecz do ... i. odnoszą się do tego samego katalogu. Po wykonaniu tego wszystkiego wie, jaki jest twój bieżący katalog roboczy.

Kiedy uruchomisz pwdwbudowaną powłokę, nie postępuje ona zgodnie z tą procedurą (choć może zrobić to w razie potrzeby) - zamiast tego pamięta ścieżkę, którą podjąłeś, aby się tu dostać. Tak więc za każdym razem, gdy wykonujesz cdpolecenie, twoja powłoka zapamiętuje to jako część ścieżki, aby dostać się tam, gdzie jesteś teraz, i pwdwypisuje to, co oblicza na podstawie wszystkich cdwykonanych poleceń - które mogą, ale nie muszą, być twoje katalog roboczy.

Sprawy mogą stać się naprawdę dziwne, kiedy wykonujesz a ln -s . fooi ciągle cdprzechodzisz do foo - /bin/pwdpowiesz, że wciąż jesteś w tym samym katalogu, ale wbudowana powłoka pwdpowie, że jesteś /foo/foo/foo/foo/foo/foo- nawet jeśli takiego katalogu nawet nie ma. (To powiedziawszy - prawdopodobnie potrafisz cd .)

Innym źródłem nieporozumień jest zmiana nazw katalogów. /bin/pwdnatychmiast przejmie zmianę, ale wbudowane pwdnie zrobi tego, dopóki nie zrobisz czegoś, co powie, że stara nazwa katalogu nie ma znaczenia.

dougmc
źródło
1
Nie odpowiadasz na pytanie, odrzucasz je.
Dmitrij Grigoryjew
4
Chociaż nie odpowiada to bezpośrednio na pytanie , myślę, że jest to przydatny post do zrozumienia różnicy między pwdwbudowanym powłoką /bin/pwdi wyjaśnienia, w jaki sposób wersja autonomiczna dostarcza bardziej przydatnych informacji (które mogą odpowiedzieć na oryginalne pytanie).
Anthony G - sprawiedliwość dla Moniki
1
Różnice te sprowadzają się do -Pi -Lopcji wymienionych w innych odpowiedziach. Krótko mówiąc, niektóre implementacje są ustawione domyślnie na jedną, niektóre na drugą. W systemie Centos, który mam pod ręką, wbudowane bash domyślnie logiczne i /bin/pwddomyślne fizycznie, ale oba akceptują obie opcje wiersza poleceń i zgadzają się na wynik, gdy zostaną podane.
IMSoP,
1
Pytanie opiera się na niepoprawnej przesłance - „czy jest jakiś sposób, aby wiedzieć, że jestem„ naprawdę ”w / var / lib / class?” To powiedziawszy ... wyjaśniając, co to tak naprawdę oznacza, pomaga mu zrozumieć, czego tak naprawdę szuka. Opcje pwd -P i -L zostały już wspomniane ...
dougmc,
1
Twój argument jest odwrócony. ls ..pokaże zawartość /var/lib, a nie /home/cpm135/public_html. cd ..jest wyjątkowy: powłoka wykonuje specjalne śledzenie „jak się tam dostałeś” i w rzeczywistości nie wykonuje chdir("..")wywołania systemowego. Jeśli chodzi o jądro, bieżący katalog roboczy powłoki ( /proc/self/cwd) jest tylko parą mountpoint: i-węzeł. To jest jak deskryptor otwartego pliku w katalogu, dlatego zmiana nazwy katalogu nie psuje powłoki. ( cd .aby zaktualizować $PWDzmienną powłoki ). Robisz użyteczny punkt, więc głosuję za tym, kiedy zostanie naprawiony
Peter Cordes,
1

Zasadniczo pytasz, czy istnieje rzeczywista ścieżka do bieżącego katalogu roboczego. Jest z pythonem i os.getcwd()funkcją

To, co widzisz poniżej, to mały test z katalogu „VirtualBox VMs” znajdującego się w moim katalogu domowym. W rzeczywistości jest to dowiązanie symboliczne do innego katalogu znajdującego się na innym dysku twardym, zamontowanego w /mnt/HDD.

bash-4.3$ file "$(pwd)"
/home/xieerqi/VirtualBox VMs: symbolic link to /mnt/HDD/VirtualBox VMs/
bash-4.3$ python -c 'import os; print os.getcwd()'
/mnt/HDD/VirtualBox VMs

Jak widać, python os.getcwd()rozwiązuje prawdziwą ścieżkę katalogu, a nie ścieżkę dowiązania symbolicznego.

Sergiy Kolodyazhnyy
źródło