Ich habe ein vollständiges Unterdateisystem in einem Pfad /home/user/system
enthält die Standard-Linux-Struktur mit den Verzeichnissen /bin
, /home
, /root
, /usr
, /var
, /etc
,…
Dieses Unterdateisystem enthält symbolische Links, entweder relative oder absolute. Die relativen Symlinks sind in Ordnung, sie bleiben im Unterdateisystem unter /home/user/system
. Aber absolute Symlinks sind problematisch, da sie auf ein Ziel außerhalb des Unterdateisystems verweisen.
Als Beispiel nehmen wir einen absoluten Symlink wie folgt an (im Unterdateisystem zu sehen):
/usr/file1 -> /usr/lib/file1
Im gesamten Dateisystem haben wir einen Link unter /home/user/system/usr/file1
die nun auf eine Datei /usr/lib/file1
zeigen außerhalb des Unterdateisystems, statt einer Datei /home/user/system/usr/lib/file1
innen das Unterdateisystem.
Ich hätte gerne ein einfaches Skript, vorzugsweise eine einzelne Befehlszeile (rsync, chroot, find, …), die jeden absoluten Symlink in einen relativen umwandelt.
Im gegebenen Beispiel würde dieser relative Link zu
/usr/file1 -> ../usr/lib/file1
Akzeptierte Antwort:
Mit den symlinks
Dienstprogramm von Mark Lord (wird von vielen Distributionen angeboten; wenn Ihre es nicht hat, bauen Sie es aus dem Quellcode):
chroot /home/user/system symlinks -cr .
Alternativ auf Systemen, die einen readlink
haben Befehl und einen -lname
Prädikat für find
(Warnung:ungetesteter Code):
cd /home/user/system &&
find . -lname '/*' -exec ksh -c '
for link; do
target=$(readlink "$link")
link=${link#./}
root=${link//+([!/])/..}; root=${root#/}; root=${root%..}
rm "$link"
ln -s "$root${target#/}" "$link"
done
' _ {} +