Il target di symlink è relativo alla directory principale della destinazione e, in caso affermativo, perché?


14

Ho la seguente struttura di file:

build/
client/
  –> index.js

E quando provo a creare un collegamento simbolico chiamato "client" all'interno della directory di build che si riferisce alla directory client nel CWD in questo modo

// Fails
$ pwd
/home/user/
$ ln -s client build/client 
$ stat build/client/index.js
stat: build/client/index.js: stat: Too many levels of symbolic links

Ottengo l'errore ELOOP visualizzato sopra. Quando cambio il percorso target in modo che sia relativo al percorso di destinazione, tutto va bene:

// Works
$ pwd
/home/user/
$ ln -s ../client build/client 
$ stat build/client/index.js
stat: <outputs file stats>

È questo il comportamento previsto e spiega perché ...


questo ha probabilmente a che fare con l'effetto che usando ../ usa il percorso assoluto per dichiarare il percorso invece del percorso relativo. una buona pratica è usare sempre il percorso assoluto
Kiwy,

Sono d'accordo con la migliore pratica in quanto ho sempre usato percorsi assoluti sia per il bersaglio che per la destinazione. Tuttavia, le pagine man affermano che i percorsi relativi possono essere usati per entrambi ...
jibsales,

Risposte:


13

Per quello che non funziona, se guardiamo il ls -lrisultato, otteniamo quanto segue:

[sparticvs@sparta test]$ ls -l build/
total 0
lrwxrwxrwx. 1 sparticvs sparticvs 6 Dec 17 16:08 client -> client

Ora per capire cosa sta succedendo qui. Diamo un'occhiata al comando che hai chiamato:

ln -s client build/client

Secondo la pagina man, ci sono due possibili corrispondenze per questo formato

SYNOPSIS
       ln [OPTION]... [-T] TARGET LINK_NAME   (1st form)
       ln [OPTION]... TARGET... DIRECTORY     (3rd form)

Si abbinerà al primo modulo (dal suo primo). Ora, il "nome target" o, clientnel tuo caso, può essere (secondo il lnmanuale completo ) stringhe arbitrarie. Non devono risolvere nulla in questo momento, ma possono risolvere qualcosa in futuro. Quello che stai creando con la tua invocazione è un "link simbolico penzolante" e il sistema non ti impedisce di crearli.

Ora la tua seconda invocazione ln -s ../client build/clientè ciò che viene chiamato un "link simbolico relativo" (come hai notato nel tuo post). C'è un secondo tipo e questo è un "link simbolico assoluto" che verrebbe chiamato facendo ln -s /home/user/client build/client.

Questo non è un bug. Secondo il manuale si afferma:

Quando si crea un collegamento simbolico relativo in una posizione diversa rispetto alla directory corrente, la risoluzione del collegamento simbolico sarà diversa dalla risoluzione della stessa stringa dalla directory corrente. Pertanto, molti utenti preferiscono prima modificare le directory nella posizione in cui verrà creato il relativo collegamento simbolico, in modo che il completamento della scheda o la risoluzione di altri file trovino la stessa destinazione di ciò che verrà inserito nel collegamento simbolico.

-- a partire dal info coreutils 'ln invocation'

Detto questo, DEVI utilizzare il percorso relativo o assoluto verso l'obiettivo.


5

Questo è davvero il comportamento previsto. Dalla ln(1)pagina man:

I collegamenti simbolici possono contenere testo arbitrario; se successivamente risolto, un collegamento relativo viene interpretato in relazione alla sua directory padre.

Quanto al perché, immagina se il collegamento simbolico fosse invece interpretato rispetto alla sua fonte piuttosto che alla sua destinazione. Quando lo risolverai più tardi, dovresti sapere qual era il tuo CWD quando lo hai creato, il che è privo di senso, per non parlare dell'impossibile.

Inoltre, in questo modo si ottiene un metodo pulito e compatto per creare una struttura di directory scheletro che è possibile rilasciare in qualsiasi punto dell'albero della directory senza interrompere i collegamenti simbolici.

Per darti un esempio di ciò che intendo, supponiamo che tu stia lavorando a un progetto e che tu abbia una intera struttura di directory impostata in questo modo:

$ ls -1 /home/you/project
thingummies/
widgets/
wizardry/

Supponiamo ora di voler creare un link simbolico widgets/all'interno wizardry/. Hai due opzioni:

$ ln -s /home/you/project/widgets /home/you/project/wizardry

o

$ ln -s ../widgets /home/you/project/wizardry

Se poi provi a /home/you/projectspostarti altrove, un link simbolico creato con il primo modulo si interromperà perché sta cercando /home/you/project/widgets. Il secondo modulo manterrà il collegamento simbolico perché sta cercando in ../widgets relazione al posto in cui si trova, indipendentemente da dove quel posto potrebbe trovarsi nella struttura di directory.

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.