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
' _ {} +