Zbyt wiele poziomów dowiązań symbolicznych

100

Utworzyłem tę strukturę plików:

test/src
test/firefox

Po uruchomieniu tego polecenia:

ln -s test/src test/firefox

Oczekiwałbym, że test/firefox/srczostanie utworzony link symboliczny wskazujący na test/src, jednak zamiast tego pojawia się ten błąd:

-bash: cd: src: Too many levels of symbolic links
  • Co ja robię źle?
  • Czy nie możesz utworzyć dowiązania symbolicznego do jednego folderu przechowywanego w jego rodzeństwie?
  • Jaki jest tego sens?
David Zorychta
źródło
Nie jestem pewien, czy podążam za tym, co zrobiłeś. Proszę zamieścić dane wyjściowe ls -ld test test/*lub dokładną sekwencję poleceń uruchomionych w celu utworzenia tych plików.
Gilles
test mkdir; mkdir test / src; test mkdir / firefox; ln -s test / src test / firefox
David Zorychta
Z tymi poleceniami cd test/firefox/srcpokazywałby błąd cd: no such file or directory: test/firefox/src, ponieważ test/firefox/srcjest wiszącym dowiązaniem symbolicznym. Czy używasz cdinnego symbolicznego łącza o nazwie src?
Gilles
Jestem pewien, że zrobiłeś coś między tym ln -sa tym cd, o czym nam nie mówisz. Zakładając, że testw bieżącym katalogu znajduje się tylko podkatalog, a cd src(lub cokolwiek co wykonałeś) powinno zgłosić błąd. Włożyłeś coś test/firefox?
Dubu,
5
A ponieważ @Gilles podpowiedział, ten link nie zrobi tego, co myślisz. Dowiązania symboliczne z względnymi celami są zawsze względne względem katalogu dowiązań symbolicznych , a nie katalogu, z którego utworzono dowiązanie. Będąc w katalogu /some/path, a ln -s test/src test/firefoxutworzy dowiązanie symboliczne wskazujące od /some/path/test/firefox/srcdo /some/path/test/firefox/test/src, a nie do /some/path/test/src.
Dubu,

Odpowiedzi:

32

Na pierwszy rzut oka to, co zasugerowałeś, działa dla mnie.

Przykład

$ mkdir -p test/src test/firefox

$ tree --noreport -fp
.
`-- [drwxrwxr-x]  ./test
    |-- [drwxrwxr-x]  ./test/firefox
    `-- [drwxrwxr-x]  ./test/src

Utwórz symboliczny link:

$ ln -s test/src test/firefox

$ tree --noreport -fp
.
`-- [drwxrwxr-x]  ./test
    |-- [drwxrwxr-x]  ./test/firefox
    |   `-- [lrwxrwxrwx]  ./test/firefox/src -> test/src
    `-- [drwxrwxr-x]  ./test/src

Uruchomienie go po raz drugi zwykle powoduje:

$ ln -s test/src test/firefox
ln: failed to create symbolic link ‘test/firefox/src’: File exists

Więc prawdopodobnie dzieje się tutaj coś innego. Podejrzewam, że masz okrągłe odniesienie, w którym link wskazuje na siebie.

Możesz użyć, findaby nieco to wyłudzić:

$ cd /suspected/directory
$ find -L ./ -mindepth 15
slm
źródło
2
find -L ./ -mindepth 15ujawnił winowajcę
użytkownika7610,
167

Jak zauważa Dubu w komentarzu, problem leży w twoich względnych ścieżkach. Miałem podobny problem z symlinkowaniem mojej konfiguracji nginx od /usr/local/etc/nginxdo /etc/nginx. Jeśli utworzysz swoje dowiązanie symboliczne w ten sposób:

cd /usr/local/etc
ln -s nginx/ /etc/nginx

W rzeczywistości utworzysz link / etc / nginx -> / etc / nginx, ponieważ ścieżka źródłowa jest względna do ścieżki łącza. Rozwiązanie jest tak proste, jak użycie ścieżek bezwzględnych:

ln -s /usr/local/etc/nginx /etc/nginx
Steen Schütt
źródło
57
Ta odpowiedź była wyraźniejsza niż druga. „Używaj ścieżek bezwzględnych”.
wulftone
1
Mogę potwierdzić, że działało to dla mnie w systemie Windows przy użyciu cygwin. Dzięki!
dimiguel
Często mam problemy z poprawieniem argumentów. W OSX i GNU Linux są one odwrócone, co jeszcze bardziej mnie dezorientuje.
Daniel W.
Nadal nie mogę uwierzyć, że to działa.
PNDA
5
Możesz użyć linków względnych , ale powinny one być oparte na katalogu, w którym znajduje się dowiązanie symboliczne . Innymi słowy: pierwszy argument powinien być taki sam, jak napisany później,cd jeśli chcesz przejść do katalogu docelowego z katalogu, w którym znajduje się plik dowiązania symbolicznego.
totymedli
9

Dowiązania symboliczne odnoszą się do katalogu nadrzędnego łącza, a nie do bieżącego katalogu lnprocesu.

Kiedy to zrobisz:

cd /top/dir
ln -s test/src test/firefox

(gdzie test/firefoxjest katalog), tworzysz test/firefox/srcdowiązanie symboliczne, którego celem jest test/src.

Jest test/srcto względne w stosunku do test/firefoxkatalogu, więc jest to dowiązanie symboliczne do /top/dir/test/firefox/test/src.

Jeśli chcesz, aby to dowiązanie symboliczne było linkiem do /top/dir/test/src, musisz napisać:

ln -s ../src test/firefox/

Lub

ln -s /top/dir/test/src test/firefox/

chociaż generalnie złym pomysłem jest tworzenie dowiązań symbolicznych do ścieżek bezwzględnych, ponieważ można je łatwo zepsuć, gdy katalogi zostaną przemianowane lub systemy plików zostaną zamontowane gdzie indziej.

Dzięki GNU lnmożesz użyć jego -ropcji, aby sam wykonał obliczenia:

$ ln -rs test/src test/firefox/
$ ls -ld test/firefox/src
lrwxrwxrwx 1 chazelas chazelas 6 Nov 29 15:59 test/firefox/src -> ../src
Stéphane Chazelas
źródło
5

Użyj ścieżki bezwzględnej zamiast ścieżki względnej, a wtedy zadziała.

Na przykład:

ln -s /home/user/test/src /home/user/test/firefox
JISHNU TU
źródło
0

Odpowiedzią jest użycie ścieżki bezwzględnej. Ale może być denerwujące, aby wpisać pełną ścieżkę do czegoś, co znajduje się w bieżącym katalogu. Możesz tego użyć, zastępując polecenia pwd. Jeśli twój cel znajduje się w bieżącym katalogu:

ln -s "$(pwd)"/target abs/path/to/link 

Jeśli Twój link powinien znajdować się w bieżącym katalogu:

ln -s /abs/path/to/target "$(pwd)"
piwo chlebowe
źródło