Czy GNU Stow może używać katalogu stow, który jest dowiązaniem symbolicznym?

10

Rozważ ten skrypt.

#! /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

Dane wyjściowe to

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

Przed uruchomieniem stowwygląda to tak:

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

Po uruchomieniu spodziewałem stowsię mylink, że będzie to wyglądać tak:

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

Zamiast tego wygląda to tak:

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

Wygląda na to, że stowpolecenie rozwiązuje rzeczywistą ścieżkę katalogu pakietu, więc zamiast wskazywać na ../mylink/package/filenią wskazuje ../mydir/package/file.

Ma to sens, aby unikać zbyt dużej pośredniczości, ale dzieje się to po cichu i nie zawsze może być pożądane. Czy istnieje sposób obejścia tego zachowania?

Edycja: zgodnie z żądaniem opiszę przykładowy przypadek użycia, w którym rozwiązanie rzeczywistej ścieżki jest niewygodne.

Łącza symboliczne są czasami używane w celu zachowania zgodności . Debian mówi o tym nawet w oficjalnej polityce . Często celem jest pojedynczy plik, ale czasem jest to katalog . Zdarza mi się mieć kilkaset w moim systemie w /usr/share/doc/pojedynkę:

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

Domyślne zachowanie stowjest w porządku, o ile nie zostanie przeniesiony cel dowiązania symbolicznego. Ale czasami żądany katalog docelowy zostaje przeniesiony. Na przykład w Debianie vim-runtimepakiet instaluje pliki w katalogu / usr / share / vim / w katalogu zależnym od wersji, takim jak /usr/share/vim/vim64wersja 6.4. Jednak pakiet będzie również aktualizować dowiązania na /usr/share/vim/vimcurrentktóry wskazał na obecnej wersji. Oznacza to, że dowiązanie symboliczne wskazuje na powiedzmy

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

zepsułby się, gdy kolejne wydanie Debiana zaktualizowało go do

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

ale dowiązanie symboliczne do

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

działałby w obu wersjach.

Ponieważ stowwykorzystuje bezwzględną kanoniczną ścieżkę katalogu stow, wywołanie jest podobne

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

spowodowałoby powstanie dowiązań symbolicznych, takich jak np .:

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

nie tak jak to:

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

(Motywacją do korzystania stowz vimcurrent/docs jest możliwość połączenia moich własnych notatek vima z dowiązaniami symbolicznymi do bieżącej dokumentacji.) Zauważ, że vimcurrentdowiązanie symboliczne kompatybilności nie jest już obecne w obecnych dystrybucjach Debiana , chociaż może być w innych, takich jak Arch Linux ; Nie jestem pewny. W każdym razie, oto skrypt, który daje ogólny pomysł na dokumentację vima:

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

Dane wyjściowe to:

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

Hipotetycznie stowmoże mieć flagę o nazwie powiedzmy --no-realpath, więc wynik będzie wyglądał mniej więcej tak:

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

Dla innych przykładów dowiązań symbolicznych, które zmieniają się z każdą wersją, oto jeszcze dwa, o których wiem na moim laptopie:

$ 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

Aby rozwiązać przypadek symlink-point-to-symlink:

#! /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

produkuje:

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

i wtedy:

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

produkuje:

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

natomiast

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

wyprodukowałoby to:

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

W hipotetycznym --no-realpathzachowaniu katalog stow byłby traktowany jak zwykły katalog.

Ta funkcja miałaby zastosowanie w scenariuszu, w którym

1) katalog stow musi być dowiązaniem symbolicznym, oraz

2) pożądane jest zachowanie tego linku w wygenerowanych linkach symbolicznych.

Chociaż nie uważam braku tej cechy za wielki brak stow, mam nadzieję, że ten przykład wyjaśnia potencjalną użyteczność nie zawsze rozwiązywania ścieżek kanonicznych.

Nathaniel M. Beaver
źródło
Czy mógłbyś podać przykładowy przypadek użycia, w którym uniknięcie tej pośredniczości byłoby pomocne? Co, jeśli mylinkzamiast tego dowiązane do mylink2którego z kolei dowiązane mydir? Jak Stow powinien zdecydować, czy powinien tworzyć dowiązania symboliczne wskazujące na ../mylink/package/filelub ../mylink2/package/fileczy ../mydir/package/file?
Adam Spiers
@AdamSpiers Mam nadzieję, że to trochę pomoże. Mógłbym to również umieścić na narzędziu do śledzenia problemów Github, jeśli wolisz.
Nathaniel M. Beaver
Dzięki @Nathaniel. Tak, to by było pomocne!
Adam Spiers
1
@AdamSpiers Gotowe! github.com/aspiers/stow/issues/11#issuecomment-507073811
Nathaniel M. Beaver

Odpowiedzi:

7

Na razie nie ma mowy.

Wewnętrznie stowznajdź bezwzględną kanoniczną ścieżkę danej ścieżki, używając chdir, aby przejść do ścieżki, a następnie użyj funkcji getcwd () z modułu POSIX, który jest interfejsem Perla dla POSIX getcwd () , aby uzyskać bezwzględną nazwę ścieżki.

Jak określono POSIX, nazwa ścieżki zawiera żadnych składników, które są .lub ..czy są dowiązania symboliczne.

Cuonglm
źródło
1
Bardzo mile widziane są sugestie, jak naprawić implementację, aby poprawnie to obsługiwać. Żądania pull są jeszcze bardziej mile widziane! :-) W celach
Adam Spiers