Faire un lien symbolique vers un chemin relatif

64

Je peux le faire:

$ pwd
/home/beau
$ ln -s /home/beau/foo/bar.txt /home/beau/bar.txt
$ readlink -f bar.txt
/home/beau/foo/bar.txt

Mais j'aimerais pouvoir faire ceci:

$ pwd
/home/beau
$ cd foo
$ ln -s bar.txt /home/beau/bar.txt
$ readlink -f /home/beau/bar.txt
/home/beau/foo/bar.txt

Est-ce possible? Puis-je en quelque sorte résoudre le chemin relatif et le transmettre ln?

Humphrey bogart
la source
Mais quel est le problème qui serait résolu avec le comportement décrit?
forcefsck
Eh bien, supposons que vous proposiez un dossier compressé au téléchargement et que vous souhaitiez donner des instructions à copier-coller sur la façon de lier de façon symbolique certains fichiers du dossier.
Humphrey Bogart
2
ln -s $(pwd)/bar.txt ~/ou inclure un script d'installation.
forcefsck
2
le lien stocke en réalité le nom que vous utilisez en ligne de commande. La résolution de ce nom dans un fichier est effectuée par rapport à l'emplacement du lien. Vous devez utiliserln -s foo/bar.txt /home/beau/bar.txt
pqnet

Réponses:

62

Si vous créez un lien symbolique vers un chemin relatif, il sera stocké sous la forme d'un lien symbolique relatif, et non absolu, comme le montre votre exemple. C'est généralement une bonne chose. Les liens symboliques absolus ne fonctionnent pas lorsque le système de fichiers est monté ailleurs.

La raison pour laquelle votre exemple ne fonctionne pas est qu'il est relatif au répertoire parent du lien symbolique et non à l'emplacement où il lnest exécuté.

Tu peux faire:

$ pwd
/home/beau
$ ln -s foo/bar.txt bar.txt
$ readlink -f /home/beau/bar.txt
/home/beau/foo/bar.txt

Ou pour que ça compte:

$ cd foo
$ ln -s foo/bar.txt ../bar.txt

Il est important de réaliser que le premier argument suivant ln -sest stocké en tant que cible du lien symbolique. Il peut s'agir de n'importe quelle chaîne arbitraire (avec les seules restrictions qu'il ne peut pas être vide ni contenir le caractère NUL), mais au moment où le lien symbolique est utilisé et résolu, cette chaîne est comprise comme un chemin d'accès relatif au fichier. répertoire parent du lien symbolique (quand il ne commence pas par /).

pingouin359
la source
2
Bien dit. Vous avez répondu à cela pendant que je tapais ma propre réponse. :)
Shadur
Je viens d'avoir une question légèrement différente - et cela répond parfaitement. Je voulais savoir comment référencer le répertoire personnel dans un lien symbolique afin qu'il fonctionne lorsque je le transférais d'un utilisateur à un autre. Je n'étais pas sûr si quelque chose comme ça ~marcherait.
Joe
"cette chaîne est comprise comme un chemin relatif vers le répertoire parent du lien symbolique" - cela explique tout!
Bojan Komazec le
24

Si vous utilisez des coreutils plus récents (j'utilise coreutils-8.22-11), une option vous le permet:

ln --help | grep relative

peut contenir du texte arbitraire; si elle est résolue ultérieurement, un lien relatif est -r, --relative crée des liens symboliques relatifs à l'emplacement du lien.

Par exemple:

$ mkdir /tmp/test
$ touch /tmp/test/to
$ ln -rs /tmp/test/to /tmp/test/from
$ ls -l /tmp/test/from
    lrwxrwxrwx 1 ptr ptr 4 aug   25 17.02 /tmp/test/to -> from
ptr
la source
Hm, pour moi, il semble qu'il n'y ait pas une telle option -r. En utilisant Mac cependant.
ivkremer
1
@ivkremer il semble que cette option est disponible depuis coreutils> = 8.16 (source: superuser.com/a/837935/403979 )
DJCrashdummy
Utiliser le drapeau relatif semblait éclaircir les problèmes de "trop ​​de niveaux de liens symboliques" que je connaissais.
Vix
12

Non désolé. Les liens symboliques sont relatifs à l'emplacement du lien, pas à l'emplacement où vous vous trouviez lorsque vous avez créé le lien. Il existe plusieurs bonnes raisons à ce comportement, la plupart impliquant le montage de systèmes de fichiers distants.

Shadur
la source
7

Il existe un petit utilitaire pratique appelé symlinks(à l'origine par Mark Lords, maintenant maintenu par J. Brandt Buckley), présent dans de nombreuses distributions Linux.

Pour convertir tous les liens symboliques absolus dans un répertoire en relatif:

symlinks -c /path/to/directory

Malheureusement, il n'y a pas d'option pour convertir un seul lien, vous devez d'abord le déplacer vers son propre répertoire.

mkdir ../tmp
mv link-to-relativize ../tmp
symlinks ../tmp
mv ../tmp/* .
rmdir ../tmp
Gilles, arrête de faire le mal
la source
Merci. liens symboliques disponibles sur github . Maintenu par J. Brandt Buckley. v1.4.3 .
Evgeny Vereshchagin
3

Tu pourrais essayer:

ln -s `pwd`/bar.txt /home/beau/bar.txt

Mais, cela crée un lien symbolique avec le chemin absolu. Votre question textuelle demande mentionne le nom de chemin relatif ...

Normalement, un chemin relatif est ce que vous voulez et ce que ln -svous donne. Je pense que ce que tu veux c'est:

cd /home/beau
ln -s foo/bar.txt bar.txt
MattBianco
la source
1

Comme les shells les plus courants développent les chemins, pour créer un lien symbolique relatif, vous devez citer le "chemin source".

En outre, le -sparamètre signifie --symbolic. lncrée des liens durs par défaut.

$ ln -s '../../relative_path' path
$ ls -al path

lrwxrwxrwx 1 empjustine empjustine 19 Aug  6 01:38 path -> ../../relative/path
emp.justine
la source
0

Si vous êtes certain qu'il n'y a aucune chance que vos points de montage changent, vous pouvez obtenir ce que vous essayez de faire dans un shell bash comme ceci:

ln -s `pwd`/bar.txt ~/bar.txt

Cela suppose que vous vous trouvez dans le répertoire cible lors de la création du lien symbolique.

mreff555
la source