Mam pełną sub-plików wewnątrz ścieżki /home/user/system
zawierającej standardową strukturę Linux z katalogów /bin
, /home
, /root
, /usr
, /var
, /etc
, ...
Ten podsystem plików zawiera dowiązania symboliczne, względne lub bezwzględne. Względne dowiązania symboliczne są w porządku, pozostają w pod-systemie plików /home/user/system
. Ale bezwzględne dowiązania symboliczne są problematyczne, ponieważ wskazują na cel poza podsystemem plików.
Jako przykład przyjmujemy bezwzględne dowiązanie symboliczne w następujący sposób (widoczne w pod-systemie plików):
/usr/file1 -> /usr/lib/file1
W ogólnym systemie plików mamy link, /home/user/system/usr/file1
który teraz wskazuje na plik /usr/lib/file1
poza podsystemem, zamiast na plik /home/user/system/usr/lib/file1
wewnątrz podsystemu.
Chciałbym mieć prosty skrypt, najlepiej pojedynczy wiersz poleceń (rsync, chroot, find, ...), który konwertuje każde absolutne dowiązanie symboliczne na względne.
W podanym przykładzie ten względny link stałby się
/usr/file1 -> ../usr/lib/file1
źródło
Odpowiedzi:
Dzięki
symlinks
narzędziu Mark Lord (oferowanemu przez wiele dystrybucji; jeśli twój go nie ma, zbuduj go ze źródła ):Alternatywnie, w systemach, które mają
readlink
polecenie i-lname
predykatfind
(ostrzeżenie: nieprzetestowany kod):źródło
_ {} +
na końcu znaleziska? Ponadtofind: paths must precede expression: ksh
pojawia się błąd, który wydaje się nie mieć sensu (ponieważ ścieżka poprzedza wyrażenie ksh)._
jest$0
na fragmencie powłoki i{} +
otrzymuje listę argumentów, które stają się$1
,$2
itp, którefor link; do …
obwodów nad (jest synonimemfor link in "$@"; do …
). Błąd zfind
wynika z literówki (jakoś udało mi się wpisać cudzysłowy zamiast pojedynczych cudzysłowów wokół argumentu do-lname
).symlinks
? Rozwiązałoby to twój problem - po prostu do tego został zaprojektowany (z irytacją, że musisz go uruchomić chrootowany ( fakechroot powinien załatwić sprawę )).Czysty bash i coreutils, zmienia dowiązania symboliczne na względne bez zbędnych
../
s na ścieżce:Możesz się zmienić:
find .
dofind /path/to/directory
konwersji dowiązań symbolicznych w tym kataloguln -fs
abyecho ln -fs
na suchoWyjaśnienie:
target="$(realpath "$l")"
- znajduje bezwzględną ścieżkę do celu dowiązania symbolicznegoln -fs
- tworzy symlink (-s
), wymuszając (-f
) przepisanie istniejącegorealpath -s "$l"
- znajduje absolutną ścieżkę do samego dowiązania symbolicznegodirname "$(realpath -s "$l")"
- znajduje bezwzględną ścieżkę do katalogu zawierającego dowiązanie symbolicznerealpath --relative-to="$(dirname "$(realpath -s "$l")")" "$target"
- znajduje ścieżkę celu względem dowiązania symbolicznego, innymi słowy: konwertuje ścieżkę bezwzględną na ścieżkę względnąźródło
if
klauzuli, aby pominąć niedziałające linki.Ten fragment bash powinien to zrobić. Pierwszy formularz wypisze, co by zrobił; drugi to zrobi. Dokładnie sprawdziłbym wynik, ponieważ jest on destrukcyjny -
ln -f
zastępuje istniejący link.źródło
Oto czyste rozwiązanie sh.
źródło
Przekształcanie wartości bezwzględnej w odnośnikach względnych jest obsługiwane przez sshfs, który montuje zdalne katalogi przez ssh.
Polecenie brzmi: tam
Polecenie, zwłaszcza
<placeholders>
, powinno być dostosowane do konkretnego środowiska.źródło