Trop de niveaux de liens symboliques

100

J'ai créé cette structure de fichier:

test/src
test/firefox

Quand j'exécute cette commande:

ln -s test/src test/firefox

Je m'attendrais à ce qu'un lien symbolique test/firefox/srcsoit créé pointant vers test/src, cependant j'obtiens cette erreur à la place:

-bash: cd: src: Too many levels of symbolic links
  • Qu'est-ce que je fais mal?
  • Ne pouvez-vous pas créer un lien symbolique vers un dossier qui est stocké dans un frère de ce dossier?
  • Quel est le but de cela?
David Zorychta
la source
Je ne suis pas sûr de suivre ce que tu as fait. Veuillez publier le résultat ls -ld test test/*ou la séquence exacte des commandes que vous avez exécutées pour créer ces fichiers.
Gilles
test mkdir; mkdir test / src; mkdir test / firefox; ln -s test / test src / firefox
David Zorychta
Avec ces commandes, cd test/firefox/srcmontrerait l’erreur cd: no such file or directory: test/firefox/src, car test/firefox/srcc’est un lien symbolique pendant. Courez-vous cdsur un autre lien symbolique appelé src?
Gilles
Je suis sûr que vous avez fait quelque chose entre le ln -set le cdque vous ne nous dites pas. En supposant qu'il n'y ait qu'un testsous - répertoire dans votre répertoire actuel, un cd srcmessage (ou ce que vous avez exécuté) devrait générer une erreur. Avez-vous mis quelque chose dans test/firefox?
Dubu
5
Et comme @Gilles a donné un indice, ce lien ne fera pas ce que vous pensez qu'il fait. Les liens symboliques avec des cibles relatives sont toujours relatifs au répertoire symlink , pas au répertoire à partir duquel vous avez créé le lien. Donc, étant dans un répertoire /some/path, a ln -s test/src test/firefoxcréera un lien symbolique pointant de /some/path/test/firefox/srcvers /some/path/test/firefox/test/src, pas vers /some/path/test/src.
Dubu

Réponses:

32

En surface, ce que vous avez suggéré d'essayer fonctionne pour moi.

Exemple

$ mkdir -p test/src test/firefox

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

Faites le lien symbolique:

$ 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

L'exécuter une deuxième fois produirait généralement ceci:

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

Donc, vous avez probablement autre chose à faire ici. Je soupçonne que vous avez une référence circulaire où un lien pointe vers lui-même.

Vous pouvez utiliser findpour trouver cela un peu:

$ cd /suspected/directory
$ find -L ./ -mindepth 15
slm
la source
2
find -L ./ -mindepth 15a révélé le coupable
user7610
168

Comme le souligne Dubu dans un commentaire, le problème réside dans vos chemins relatifs. J'ai eu un problème similaire en liant ma configuration nginx de /usr/local/etc/nginxà /etc/nginx. Si vous créez votre lien symbolique comme ceci:

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

Vous ferez en fait le lien / etc / nginx -> / etc / nginx, car le chemin source est relatif au chemin du lien. La solution est aussi simple que d’utiliser des chemins absolus:

ln -s /usr/local/etc/nginx /etc/nginx
Steen Schütt
la source
58
Cette réponse était plus claire que l'autre. "Utilisez des chemins absolus."
wulftone
1
Je peux confirmer que cela a fonctionné pour moi sur Windows en utilisant cygwin. Merci!
Dimiguel
J'ai souvent du mal à obtenir les arguments corrects. Sur OSX et GNU Linux, ils sont inversés, ce qui me rend encore plus confus.
Daniel W.
Je n'arrive toujours pas à croire que ça marche.
PNDA
5
Vous pouvez utiliser des liens relatifs , mais ils doivent être basés sur le répertoire contenant le lien symbolique . En d'autres termes: le premier argument devrait être le même que celui que vous écririez aprèscd si vous souhaitez accéder au répertoire ciblé à partir du répertoire où se trouve le fichier du lien symbolique.
totymedli
9

Les liens symboliques sont relatifs au répertoire parent du lien, pas au répertoire actuel du lnprocessus.

Quand tu fais:

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

(où test/firefoxest un répertoire), vous test/firefox/srccréez un lien symbolique dont la cible est test/src.

C'est test/srcrelatif au test/firefoxrépertoire, donc c'est un lien symbolique vers /top/dir/test/firefox/test/src.

Si vous voulez que ce lien symbolique soit un lien vers /top/dir/test/src, vous devez écrire:

ln -s ../src test/firefox/

Ou

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

Bien que ce soit généralement une mauvaise idée de créer des liens symboliques vers des chemins absolus car ils sont facilement cassés lorsque les répertoires sont renommés ou que les systèmes de fichiers sont montés ailleurs.

Avec GNU ln, vous pouvez utiliser son -roption pour lui permettre de faire le calcul par lui-même:

$ 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
la source
5

Utilisez le chemin absolu au lieu du chemin relatif, alors cela fonctionnera.

Par exemple:

ln -s /home/user/test/src /home/user/test/firefox
JISHNU TU
la source
0

La réponse est d'utiliser un chemin absolu. Mais il peut être ennuyeux de taper le chemin complet pour quelque chose qui se trouve dans le répertoire courant. Vous pouvez utiliser la substitution de commande de pwd pour éviter cela. Si votre cible est dans le répertoire actuel:

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

Si votre lien doit être dans le répertoire actuel:

ln -s /abs/path/to/target "$(pwd)"
bière à pain
la source