Troppi livelli di collegamenti simbolici


100

Ho creato questa struttura di file:

test/src
test/firefox

Quando eseguo questo comando:

ln -s test/src test/firefox

Mi aspetto test/firefox/srcche venga creato un collegamento simbolico che punta a test/src, tuttavia ottengo invece questo errore:

-bash: cd: src: Too many levels of symbolic links
  • Che cosa sto facendo di sbagliato?
  • Non è possibile creare un collegamento simbolico a una cartella memorizzata in un fratello di quella cartella?
  • Che senso ha questo?

Non sono sicuro di seguire quello che hai fatto. Pubblica l'output ls -ld test test/*o l'esatta sequenza di comandi che hai eseguito per creare questi file.
Gilles,

test di mkdir; mkdir test / src; mkdir test / firefox; ln -s test / src test / firefox
David Zorychta

Con questi comandi, cd test/firefox/srcmostrerebbe l'errore cd: no such file or directory: test/firefox/src, perché test/firefox/srcè un collegamento simbolico penzolante. Stai correndo cdsu un altro link simbolico chiamato src?
Gilles,

Sono sicuro che hai fatto qualcosa tra il ln -se il cdche non ci dici. Supponendo che ci sia solo una testsottodirectory nella directory corrente, un cd src(o qualunque cosa tu abbia eseguito) dovrebbe generare un errore. Hai messo qualcosa dentro test/firefox?
Dubu,

5
E dato che @Gilles ha dato un suggerimento, quel link non farà quello che pensi che faccia. I collegamenti simbolici con destinazioni relative sono sempre relativi alla directory dei collegamenti simbolici , non alla directory da cui è stato creato il collegamento. Quindi, trovandosi in una directory /some/path, a ln -s test/src test/firefoxcreerà un collegamento simbolico che punta da /some/path/test/firefox/srca /some/path/test/firefox/test/src, non a /some/path/test/src.
Dubu,

Risposte:


32

A prima vista, ciò che hai suggerito di aver provato ha funzionato per me.

Esempio

$ mkdir -p test/src test/firefox

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

Crea il collegamento simbolico:

$ 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

Eseguirlo una seconda volta in genere produrrebbe questo:

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

Quindi probabilmente hai qualcos'altro in corso qui. Sospetto che tu abbia un riferimento circolare in cui un link punta di nuovo su se stesso.

Puoi usarlo findper capire un po ':

$ cd /suspected/directory
$ find -L ./ -mindepth 15

2
find -L ./ -mindepth 15rivelato il colpevole
user7610

168

Come Dubu sottolinea in un commento, il problema risiede nei tuoi percorsi relativi. Ho avuto un problema simile nel collegamento simbolico della mia configurazione nginx da /usr/local/etc/nginxa /etc/nginx. Se crei il tuo link simbolico in questo modo:

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

In effetti, creerai il collegamento / etc / nginx -> / etc / nginx, perché il percorso di origine è relativo al percorso del collegamento. La soluzione è semplice come usare percorsi assoluti:

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

58
Questa risposta è stata più chiara dell'altra. "Usa percorsi assoluti."
wulftone,

1
Posso confermare che questo ha funzionato per me su Windows utilizzando cygwin. Grazie!
dimiguel,

Ho spesso problemi a correggere gli argomenti. Su OSX e GNU Linux, sono invertiti, il che mi confonde ancora di più.
Daniel W.

Non riesco ancora a credere che funzioni.
PNDA,

5
È possibile utilizzare i collegamenti relativi , ma devono essere basati sulla directory in cui si trova il collegamento simbolico . In altre parole: il primo argomento dovrebbe essere lo stesso che scriveresti dopocd se desideri andare nella directory di destinazione dalla directory in cui si trova il file del collegamento simbolico.
totymedli,

9

I collegamenti simbolici sono relativi alla directory principale del collegamento, non alla directory corrente del lnprocesso.

Quando lo fai:

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

(dove si test/firefoxtrova una directory), stai creando un test/firefox/srccollegamento simbolico il cui obiettivo è test/src.

Questo test/srcè relativo alla test/firefoxdirectory, quindi è un link simbolico a /top/dir/test/firefox/test/src.

Se si desidera che quel collegamento simbolico sia un collegamento a /top/dir/test/src, è necessario scrivere:

ln -s ../src test/firefox/

O

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

sebbene sia generalmente una cattiva idea creare collegamenti simbolici a percorsi assoluti poiché vengono facilmente interrotti quando le directory vengono rinominate o i filesystem vengono montati altrove.

Con GNU ln, puoi usare la sua -ropzione per consentirgli di effettuare il calcolo da solo:

$ ln -rs test/src test/firefox/
$ ls -ld test/firefox/src
lrwxrwxrwx 1 chazelas chazelas 6 Nov 29 15:59 test/firefox/src -> ../src

5

Usa il percorso assoluto invece del percorso relativo, quindi funzionerà.

Per esempio:

ln -s /home/user/test/src /home/user/test/firefox

0

La risposta è usare il percorso assoluto. Ma può essere fastidioso digitare il percorso completo per qualcosa che si trova nella directory corrente. È possibile utilizzare la sostituzione dei comandi di pwd per evitarlo. Se il tuo target si trova nella directory corrente:

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

Se il tuo link dovrebbe essere nella directory corrente:

ln -s /abs/path/to/target "$(pwd)"
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.