GNU Stow peut-il utiliser un répertoire stow qui est un lien symbolique?


10

Considérez ce script.

#! /usr/bin/env bash

mkdir -p target
mkdir -p mydir/package/
touch mydir/package/file

ln --symbolic mydir mylink
file mylink

stow --verbose --dir=./mylink --target=./target package

file target/file

La sortie est

mylink: symbolic link to mydir
LINK: file => ../mydir/package/file
target/file: symbolic link to ../mydir/package/file

Avant de courir stow, cela ressemble à ceci:

.
├── mydir
│   └── package
│       └── file
├── mylink -> mydir
└── target

Après avoir exécuté stow, mylinkje m'attendais à ce que cela ressemble à ceci:

.
├── mydir
│   └── package
│       └── file
├── mylink -> mydir
└── target
    └── file -> ../mylink/package/file

Cependant, à la place, cela ressemble à ceci:

.
├── mydir
│   └── package
│       └── file
├── mylink -> mydir
└── target
    └── file -> ../mydir/package/file

Il semble que la stowcommande résout le chemin réel du répertoire du package, donc au lieu de le pointer, ../mylink/package/fileil pointe vers ../mydir/package/file.

Cela est logique pour éviter trop d'indirection, mais cela se produit en silence et peut ne pas toujours être souhaitable. Existe-t-il un moyen de contourner ce comportement?

Edit: Selon la demande, je vais décrire un exemple de cas d'utilisation où la résolution du chemin réel n'est pas pratique.

Les liens symboliques sont parfois utilisés pour des raisons de compatibilité . Debian en parle même dans la politique officielle . Souvent, la cible est un fichier unique, mais parfois c'est un répertoire . Il se trouve que j'en ai quelques centaines sur mon système /usr/share/doc/seul:

$ find /usr/share/doc -xtype d -type l | wc -l
325

Le comportement par défaut de stowest correct tant que la cible du lien symbolique n'est pas déplacée. Mais parfois, le répertoire ciblé souhaité est déplacé. Par exemple, sur Debian, le vim-runtimepaquet installe les fichiers sous / usr / share / vim / dans un répertoire qui dépend de la version, comme /usr/share/vim/vim64pour la version 6.4. Cependant, le paquet serait également mettre à jour un lien symbolique à /usr/share/vim/vimcurrentqui pointait vers la version actuelle. Cela signifie qu'un lien symbolique pointant vers, disons

/usr/share/vim/vim64/doc/cmdline.txt

se briserait lors de la prochaine mise à jour de Debian

/usr/share/vim/vim70/doc/cmdline.txt

mais un lien symbolique vers

/usr/share/vim/vimcurrent/doc/cmdline.txt

fonctionnerait dans les deux versions.

Depuis stowutilise le chemin canonique absolu du répertoire stow, une invocation comme

stow --dir=/usr/share/vim/vimcurrent --target=./my-vim-docs doc

entraînerait des liens symboliques comme, par exemple, ceci:

$ file cmdline.txt
cmdline.txt: symbolic link to ../../../../../usr/share/vim/vim64/doc/cmdline.txt

pas comme ça:

$ file cmdline.txt
cmdline.txt: symbolic link to ../../../../../usr/share/vim/vimcurrent/doc/cmdline.txt

(La motivation pour utiliser stowon vimcurrent/docs est de pouvoir mélanger mes propres notes vim avec des liens symboliques vers la documentation actuelle.) Notez que le vimcurrentlien symbolique de compatibilité n'est plus présent dans les distributions Debian actuelles , bien qu'il puisse l'être dans d'autres comme Arch Linux ; Je ne suis pas sûr. Dans tous les cas, voici un script qui donne l'idée générale de la documentation de vim:

#! /usr/bin/env bash
mkdir -p target
ln --symbolic /usr/share/vim/vim80 vimcurrent
stow --verbose --dir=./vimcurrent --target=./target pack
file target/dist

La sortie est:

LINK: dist => ../../../../../usr/share/vim/vim80/pack/dist
target/dist: symbolic link to ../../../../../usr/share/vim/vim80/pack/dist

Hypothétiquement, stowpourrait avoir un indicateur appelé, disons --no-realpath, donc la sortie ressemblerait à quelque chose comme ceci à la place:

LINK: dist => ./vimcurrent/pack/dist
target/dist: symbolic link to ./vimcurrent/pack/dist

Pour d'autres exemples de liens symboliques de compatibilité qui changent avec chaque version, voici deux autres que je connais sur mon ordinateur portable:

$ file /usr/share/go
/usr/share/go: symbolic link to go-1.10
$ file /usr/share/mscore
/usr/share/mscore: symbolic link to mscore-2.1

Pour résoudre le cas des liens symboliques-vers-liens symboliques:

#! /usr/bin/env bash
mkdir -p target
mkdir -p mydir/package/
touch mydir/package/file
ln --symbolic mydir mylink
ln --symbolic mylink mylink2
namei mylink2

produit:

f: mylink2
 l mylink2 -> mylink
   l mylink -> mydir
     d mydir

puis:

$ stow --verbose --dir=./mylink2 --target=./target package
$ file target/file

produit:

LINK: file => ../mydir/package/file
target/file: symbolic link to ../mydir/package/file

tandis que

$ stow --no-realpath --verbose --dir=./mylink2 --target=./target package
$ file target/file

produirait ceci:

LINK: file => ../mylink2/package/file
target/file: symbolic link to ../mylink2/package/file

Donc, dans le --no-realpathcomportement hypothétique , il traiterait le répertoire stow comme un répertoire normal.

Cette fonctionnalité serait applicable dans un scénario où

1) le répertoire stow doit être un lien symbolique, et

2) il est souhaitable de conserver ce lien dans les liens symboliques générés.

Bien que je ne considère pas le manque de cette fonctionnalité comme une grande lacune stow, j'espère que cet exemple clarifie l'utilité potentielle de ne pas toujours résoudre les chemins canoniques.


Pourriez-vous donner un exemple d'utilisation où éviter cette indirection serait utile? Et si à la mylinkplace un lien symbolique vers mylink2lequel à son tour était lié à un lien symbolique mydir? Comment Stow devrait-il décider s'il doit créer des liens symboliques pointant vers ../mylink/package/fileou ../mylink2/package/fileou ../mydir/package/file?
Adam Spires

@AdamSpiers J'espère que cela aide un peu. Je pourrais aussi mettre cela sur le tracker de problème Github, si vous préférez.
Nathaniel M. Beaver

Merci @Nathaniel. Oui, ce serait utile!
Adam Spires

Réponses:


7

Pour l'instant, il n'y a aucun moyen.

En interne, stowrecherchez le chemin canonique absolu du chemin donné en utilisant chdir pour vous déplacer dans le chemin, puis utilisez la fonction getcwd () du module POSIX, qui est l'interface Perl pour POSIX getcwd () , pour obtenir le nom du chemin absolu.

Comme spécifié POSIX, le nom de chemin ne doit contenir aucun composant qui soit .ou .., ou sont des liens symboliques.


1
Les suggestions sur la façon de corriger l'implémentation pour gérer cela correctement sont les bienvenues. Les demandes de tirage sont encore plus les bienvenues! :-) Pour référence, le problème a été signalé ici: github.com/aspiers/stow/issues/11
Adam Spires
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.