J'ai un sous-système de fichiers complet dans un chemin /home/user/system contenant la structure Linux standard avec les répertoires /bin , /home , /root , /usr , /var , /etc ,…
Ce sous-système de fichiers contient des liens symboliques, relatifs ou absolus. Les liens symboliques relatifs sont très bien, ils restent dans le sous-système de fichiers sous /home/user/system . Mais les liens symboliques absolus sont problématiques, car ils pointent vers une cible en dehors du sous-système de fichiers.
À titre d'exemple, nous supposons un lien symbolique absolu comme suit (vu à l'intérieur du sous-système de fichiers) :
/usr/file1 -> /usr/lib/file1
Dans le système de fichiers global, nous avons un lien à /home/user/system/usr/file1 qui pointe maintenant vers un fichier /usr/lib/file1 en dehors du sous-système de fichiers, au lieu d'un fichier /home/user/system/usr/lib/file1 à l'intérieur le sous-système de fichiers.
Je voudrais avoir un script simple, de préférence une seule ligne de commande (rsync, chroot, find, …) qui convertit chaque lien symbolique absolu en lien relatif.
Dans l'exemple donné, ce lien relatif deviendrait
/usr/file1 -> ../usr/lib/file1
Réponse acceptée :
Avec les symlinks utilitaire de Mark Lord (offert par de nombreuses distributions ; si la vôtre ne l'a pas, construisez-le à partir des sources) :
chroot /home/user/system symlinks -cr .
Alternativement, sur les systèmes qui ont un readlink commande et un -lname prédicat pour find (attention :code non testé) :
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
' _ {} +