Ich habe ein komplettes Unterdateisystem in einem Pfad /home/user/system
die Standard - Linux - Struktur mit Verzeichnissen enthalten /bin
, /home
, /root
, /usr
, /var
, /etc
, ...
Dieses Unterdateisystem enthält symbolische Links, entweder relativ oder absolut. Die relativen Symlinks sind in Ordnung, sie bleiben im Sub-Dateisystem unter /home/user/system
. Absolute Symlinks sind jedoch problematisch, da sie auf ein Ziel außerhalb des Sub-Dateisystems verweisen.
Als Beispiel nehmen wir einen absoluten Symlink wie folgt an (innerhalb des Sub-Dateisystems):
/usr/file1 -> /usr/lib/file1
Im gesamten Dateisystem haben wir an /home/user/system/usr/file1
dieser Stelle einen Link zu einer Datei /usr/lib/file1
außerhalb des Sub-Dateisystems anstelle einer Datei /home/user/system/usr/lib/file1
innerhalb des Sub-Dateisystems.
Ich hätte gerne ein einfaches Skript, vorzugsweise eine einzelne Befehlszeile (rsync, chroot, find, ...), die jeden absoluten Symlink in einen relativen konvertiert.
In dem gegebenen Beispiel würde dieser relative Link werden
/usr/file1 -> ../usr/lib/file1
quelle
Antworten:
Mit dem
symlinks
Dienstprogramm von Mark Lord (das von vielen Distributionen angeboten wird; wenn Sie es nicht haben, bauen Sie es aus dem Quellcode auf ):Alternativ dazu können Sie auf Systemen mit einem
readlink
Befehl und einem-lname
Prädikat fürfind
(Warnung: ungetesteter Code) Folgendes tun:quelle
_ {} +
am Ende des Fundes? Außerdem erhalte ich einen Fehler,find: paths must precede expression: ksh
der nicht sinnvoll zu sein scheint (da der Pfad vor dem Ausdruck ksh steht)._
ist$0
für den Shell - Schnipsel, und{} +
wird durch die Liste der Argumente ersetzt, wird$1
,$2
usw. , diefor link; do …
über Maschen (es ist gleichbedeutend mitfor link in "$@"; do …
). Der Fehler vonfind
ist auf einen Tippfehler zurückzuführen (ich habe es irgendwie geschafft, Anführungszeichen anstelle von einfachen Anführungszeichen um das Argument zu schreiben-lname
).symlinks
? Es würde Ihr Problem lösen - das ist im Grunde das, wofür es entwickelt wurde (mit dem Ärger, dass Sie es chrooted ausführen müssen ( fakechroot sollte den Trick machen)).Pure bash & coreutils, ändert Symlinks in relative ohne unnötige
../
s im Pfad:Du kannst ändern:
find .
bisfind /path/to/directory
zu Symlinks in diesem Verzeichnis zu konvertierenln -fs
umecho ln -fs
für einen TrockenlaufErläuterung:
target="$(realpath "$l")"
- Findet den absoluten Pfad zum Symlink-Zielln -fs
- Erzeugt symlink (-s
), erzwingt (-f
) das Umschreiben bestehenderrealpath -s "$l"
- findet den absoluten Pfad zum Symlink selbstdirname "$(realpath -s "$l")"
- Findet den absoluten Pfad zum Verzeichnis, das den Symlink enthältrealpath --relative-to="$(dirname "$(realpath -s "$l")")" "$target"
- findet den Pfad des Ziels relativ zu symlink, dh konvertiert den absoluten in den relativen Pfadquelle
if
Klausel hinzuzufügen , um defekte Links zu überspringen.Dieses Bash-Snippet sollte es tun. Das erste Formular gibt aus, was es tun würde. der zweite wird es tun. Ich würde die Ausgabe sorgfältig prüfen, da sie destruktiv ist -
ln -f
der vorhandene Link wird überschrieben.quelle
Hier ist eine reine sh-Lösung.
quelle
Das Umwandeln von absoluten in relative Links wird von sshfs unterstützt, das entfernte Verzeichnisse über ssh bereitstellt.
Der Befehl lautet: Dort
Der Befehl, insbesondere der Befehl,
<placeholders>
muss an die jeweilige Umgebung angepasst werden.quelle