Pourquoi mon lien symbolique ne fonctionne-t-il pas?

24

J'essaie de mieux comprendre les liens symboliques ... et je n'ai pas beaucoup de chance. Voici ma sortie shell réelle avec le nom d'utilisateur / hôte modifié:

username@host:~$ mkdir actual
username@host:~$ mkdir proper
username@host:~$ touch actual/file-1.txt
username@host:~$ echo "file 1" > actual/file-1.txt
username@host:~$ touch actual/file-2.txt
username@host:~$ echo "file 2" > actual/file-2.txt
username@host:~$ ln -s actual/file-1.txt actual/file-2.txt proper
username@host:~$ # Now, try to use the files through their links
username@host:~$ cat proper/file-1.txt
cat: proper/file-1.txt: No such file or directory
username@host:~$ cat proper/file-2.txt
cat: proper/file-2.txt: No such file or directory
username@host:~$ # Check that actual files do in fact exist
username@host:~$ cat actual/file-1.txt
file 1
username@host:~$ cat actual/file-2.txt
file 2
username@host:~$ # Remove the links and go home :(
username@host:~$ rm proper/file-1.txt
username@host:~$ rm proper/file-2.txt

Je pensais qu'un lien symbolique était censé fonctionner de manière transparente, dans le sens où vous pourriez opérer sur le fichier vers lequel il pointe comme si vous accédiez directement au fichier (sauf bien sûr dans le cas rmoù bien sûr le lien est simplement supprimé ).

orokusaki
la source
Comment votre disque est-il formaté? Quel système de fichiers utilisez-vous? (FAT ne prend pas en charge les liens symboliques mais si vous essayez de créer sur un système de fichiers FAT, cela devrait donner une erreur.)
Nicole Hamilton
@NicoleHamilton - C'est ext4 (selon df -T) - le résultat ci-dessus vous est-il également étrange?
orokusaki
@orokusaki Pas étrange. Voir ma réponse ci-dessous. Juste un avertissement, pas besoin de toucher des fichiers pour les toucher. Ils n'ont même pas besoin d'exister. Juste pour vous faire économiser de la frappe!
nerdwaller

Réponses:

50

Les liens symboliques ont tendance à aimer les chemins complets ou par rapport au lien, sinon ils peuvent souvent être recherchés file-1.txtlocalement (assez curieusement).

Naviguez properet exécutez ls -let vous pouvez voir que le lien symbolique recherche actual/file-1.txt, quand il devrait l'être ../actual/file-1.txt.

Vous avez donc deux options:

  1. Donnez le chemin complet

    ln -s ~/actual/file-1.txt ~/actual/file-2.txt ~/proper
  2. Accédez au dossier dans lequel vous souhaitez que le lien se trouve et créez un lien à partir de là

    cd proper
    ln -s ../actual/file-1.txt ../actual/file-2.txt ./

Modifier : une astuce pour enregistrer la saisie.

Tu pourrais juste faire ln -s ~/actual/file-{1,2}.txt ~/proper

Les éléments entre les accolades sont remplacés et placés les uns après les autres, créant la commande

ln -s ~/actual/file-1.txt ~/actual/file-2.txt ~/proper

qui relie les deux fichiers au répertoire cible. Enregistre certains types de frappe à mesure que vous progressez dans le shell.

nerdwaller
la source
2
Merci - j'étais sur le point d'arracher mes cheveux avant de lire votre réponse.
orokusaki
1
C'est parfois déroutant, c'est sûr! Linux a tendance à être très littéral, donc si vous dites faire quelque chose - ce sera le cas. Soyez prudent avec les liens symboliques de cette façon, j'en ai écrasé un ou deux auparavant (spécifiez simplement le nom sans barre oblique de fin). Ne faites pas non plus rm -rf *de dossier avec un lien symbolique - vous pouvez effacer le dossier auquel il est lié. Faites juste rm symlinkname. Juste quelques petites choses sur
lesquelles
3

Le problème est l'utilisation de chemins relatifs. Si vous spécifiez votre création de lien avec le chemin explicite complet, cela fonctionne.

$ ln -s ~ / actual / file1.txt ~ / actual / file2.txt ~ / proper /

$ cat proper / file1.txt

fichier 1

$

Votre exemple crée des liens properqui recherchent un sous-répertoire nommé actual sous le répertoire actuel, plutôt que le parent prévu des deux.

Don Simon
la source
1

Les liens symboliques peuvent être délicats. En substance, un lien symbolique est un fichier qui contient un nom de fichier / chemin d'accès pour un autre fichier (et qui est marqué pour un traitement spécial). Si le chemin d'accès dans le fichier de liens commence par ' /', il est alors traité comme un chemin d'accès absolu et les choses sont assez simples. S'il ne commence pas par une barre oblique, il est traité comme un chemin relatif - par rapport au répertoire où se trouve le lien. (Cela est vrai que le nom contienne ou non des barres obliques.) Ainsi, vous avez créé proper/file–1.txtun lien vers « actual/file–1.txt», et lorsque vous avez essayé d'y accéder, le système a tenté d'accéder proper/actual/file–1.txt. Tu aurais dû dire

ln s  ../actual/file1.txt  ../actual/file2.txt  proper

Au fait, vous n'aviez pas besoin des touchcommandes.  echo "file 1" > actual/file–1.txtsuffit de créer actual/file–1.txt.

Scott
la source
0

Un problème connexe, et il peut être évident pour beaucoup, mais m'a laissé perplexe pendant quelques minutes: si vous créez un lien symbolique dans un répertoire qui est lui-même lié, ou s'il y a un lien symbolique dans le chemin du répertoire de travail actuel, vous pourriez rencontrer des problèmes avec les liens symboliques qui ne fonctionnent pas.

Utilisez cd ..et à ls -lplusieurs reprises pour voir si vos répertoires parents sont eux-mêmes liés par des liens symboliques.

Si vous devez créer un lien symbolique cdvers le répertoire cible d'origine et y créer de nouveaux liens symboliques, les chemins relatifs sont donc précis.

Ou pour le dire autrement: le chemin relatif est de l'origine à la cible. Si l'Origine est par la suite liée par un lien symbolique, c'est OK. Mais vous pourriez rencontrer des problèmes lors de la configuration d'un nouveau nom de lien d'origine dans un répertoire qui est lui-même en quelque sorte lié par un lien symbolique.

Chrisky
la source
1
Au lieu de « cd ..et à ls -lplusieurs reprises», vous pouvez utiliser namei -mox $PWD. Un autre moyen utile de savoir s'il y a des liens symboliques le long du chemin est d'utiliser pwd -P, qui vous donne un chemin vers le répertoire courant qui ne contient aucun lien symbolique (donc si pwdet pwd -Pdonnez une sortie différente, vous savez qu'il y a un lien symbolique quelque part le long du chemin ).
Ansa211
0

Lorsque vous essayez de créer un lien vers un fichier qui n'existe pas (ou si vous avez indiqué le chemin de manière incorrecte), ln -s ne génère pas d'erreur. Il crée un lien mais lorsque vous essayez «chat» sur ce lien, il indique qu'aucun fichier n'a été trouvé. Même lorsque vous pouvez le voir en utilisant ls. Dans de tels cas, vérifiez toujours votre chemin de fichier.

ubuntu@ip-172-31-80-155:~/lab5$ ln -s etc/ufw/ufw.conf link1
ubuntu@ip-172-31-80-155:~/lab5$ ls -al
total 5360
drwxrwxr-x 2 ubuntu ubuntu    4096 Mar  9 18:56 .
drwxr-xr-x 7 ubuntu ubuntu    4096 Mar  9 18:42 ..
-rwxr--r-- 1 ubuntu ubuntu 5478400 Mar  9 18:32 backup.tar
lrwxrwxrwx 1 ubuntu ubuntu      16 Mar  9 18:56 link1 -> etc/ufw/ufw.conf
ubuntu@ip-172-31-80-155:~/lab5$ cat link1
cat: link1: No such file or directory

Parce que le fichier etc / ufw / ufw.conf n'existe pas. Le chemin correct est /etc/ufw/ufw.conf

ubuntu@ip-172-31-80-155:~/lab5$ ln -s /etc/ufw/ufw.conf link2
ubuntu@ip-172-31-80-155:~/lab5$ ls -l
total 5352
-rwxr--r-- 1 ubuntu ubuntu 5478400 Mar  9 18:32 backup.tar
lrwxrwxrwx 1 ubuntu ubuntu      16 Mar  9 18:56 link1 -> etc/ufw/ufw.conf
lrwxrwxrwx 1 ubuntu ubuntu      17 Mar  9 19:00 link2 -> /etc/ufw/ufw.conf
ubuntu@ip-172-31-80-155:~/lab5$ cat link2
# /etc/ufw/ufw.conf
#

# Set to yes to start on boot. If setting this remotely, be sure to add a rule
# to allow your remote connection before starting ufw. Eg: 'ufw allow 22/tcp'
ENABLED=no

# Please use the 'ufw' command to set the loglevel. Eg: 'ufw logging medium'.
# See 'man ufw' for details.
LOGLEVEL=low
sindhura
la source
Il y a déjà une meilleure réponse, et la première partie, que ln -s"parfois" ne vérifie pas l'existence de la cible est tout simplement fausse.
RalfFriedl