Utworzyłem dowiązanie symboliczne z bezwzględną ścieżką do katalogu (Blink) i mam na przykład następujące drzewo:
$ ls -l /tmp/A
total 0
lrwxrwxrwx 1 root root 6 Apr 3 12:27 Blink -> /tmp/B
-rw-r--r-- 1 root root 0 Apr 3 12:27 foo
$ ls -l /tmp/B
total 0
-rw-r--r-- 1 root root 0 Apr 3 12:27 bar
następnie przechodzę do / tmp / A i zmieniam katalog na Blink:
$ cd /tmp/A
$ pwd
/tmp/A
$ cd Blink
$ pwd
/tmp/A/Blink
cd ..
zwraca mnie, /tmp/A
ale jeśli napiszę na przykład ls ../foo
, otrzymam błąd:
ls: ../foo: No such file or directory
wbudowana komenda cd rozpoznaje ścieżkę w razie potrzeby, ale zewnętrzny ls uważa .. za wyższy poziom / tmp / B i dlatego nie może znaleźć foo.
Jaki jest tutaj problem? Czy mogę pobrać plik foo z / tmp / A / Blink za pomocą ścieżki względnej, takiej jak ../foo?
Odpowiedzi:
Nie sądzę, że możesz to zrobić. Obecnie powłoki śledzą, w jaki sposób dotarły na miejsce, śledzą bieżący katalog roboczy według nazwy, a nie tylko polegają na systemie plików i systemie operacyjnym, aby go zachować. Oznacza to, że wbudowane narzędzie
cd
może „cofnąć” link symboliczny, zamiast bezpośrednio podążać za łańcuchami „..”.Ale po uruchomieniu
ls ../foo
,ls
nie jest świadoma, że powłoka dostał się do katalogu, wykonując dowiązania symboliczne.ls
zrobi astat()
na „../foo”. Część „..” pochodzi z bieżącego katalogu, który ma tylko jeden wpis „..” dla swojego rodzica. Cała dowiązanie symboliczne nie zmienia sposobu, w jaki katalogi mają pojedyncze „.” i pojedynczy wpis „..”. Dowiązania symboliczne pozwalają jądrze wstawić dodatkową warstwę pośrednią do ścieżek plików. Kiedy przekazujesz „../whokolwiek” doopen()
lubstat()
, jądro po prostu używa bieżącego katalogu roboczego procesu, wykonując wywołanie, aby dowiedzieć się, który pojedynczy katalog ma nazwę „..”.źródło
Powłoka przechowuje bieżący katalog roboczy w
$PWD
. To, co jest wykorzystywane do poleceń wbudowanychcd
ipwd
, i traktuje dowiązania jako normalnych katalogach, jak widzieliście. Czasami jest to pomocne, a czasem nie.Możesz znaleźć prawdziwy katalog, używając
pwd
(wpiszhelp pwd
więcej szczegółów):Podobnie
cd
ma opcję-P
(znowu,help cd
jest twoim przyjacielem):Na koniec możesz całkowicie wyłączyć „funkcję”:
źródło
set -P
zachowanie i ls zaczyna mieć sens. :)Bruce i ams udzielili pięknych odpowiedzi, wyjaśniając zachowanie z tyłu. Ale żeby faktycznie zrobić to, o
ls ../foo
co prosiłeś, możesz pójść z czymś takimźródło
Nie możesz tego zrobić, bo
/tmp/A/Blink
tak naprawdę jest/tmp/B
. Więcls ../A/foo
działa.Zamiast tego możesz uznać za przydatne możliwość cd do prawdziwego
/tmp/B
katalogu zamiast do aliasu/tmp/A/Blink
. Aby to zrobić, możesz użyć następującej funkcji zamiastcd
(którą możesz umieścić w swoim .bashrc)lcd
, oczywiście, działa zarówno dla normalnych, jak i symbolicznych katalogów.Uwaga:
readlink -f
działa na ostateczny cel linku (gdy linki są połączone łańcuchowo) ..źródło
cd -P
wydaje się prostsze.