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 stow
wygląda to tak:
.
├── mydir
│ └── package
│ └── file
├── mylink -> mydir
└── target
Po uruchomieniu spodziewałem stow
się 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 stow
polecenie rozwiązuje rzeczywistą ścieżkę katalogu pakietu, więc zamiast wskazywać na ../mylink/package/file
nią 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 stow
jest 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-runtime
pakiet instaluje pliki w katalogu / usr / share / vim / w katalogu zależnym od wersji, takim jak /usr/share/vim/vim64
wersja 6.4. Jednak pakiet będzie również aktualizować dowiązania
na /usr/share/vim/vimcurrent
któ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ż stow
wykorzystuje 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 stow
z vimcurrent/docs
jest możliwość połączenia moich własnych notatek vima z dowiązaniami symbolicznymi do bieżącej dokumentacji.) Zauważ, że vimcurrent
dowią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 stow
moż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-realpath
zachowaniu 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.
mylink
zamiast tego dowiązane domylink2
którego z kolei dowiązanemydir
? Jak Stow powinien zdecydować, czy powinien tworzyć dowiązania symboliczne wskazujące na../mylink/package/file
lub../mylink2/package/file
czy../mydir/package/file
?Odpowiedzi:
Na razie nie ma mowy.
Wewnętrznie
stow
znajdź 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.źródło