Tengo un subsistema de archivos completo dentro de una ruta /home/user/system
que contiene la estructura estándar de Linux con directorios /bin
, /home
, /root
, /usr
, /var
, /etc
,…
Este subsistema de archivos contiene enlaces simbólicos, ya sean relativos o absolutos. Los enlaces simbólicos relativos están bien, permanecen dentro del subsistema de archivos en /home/user/system
. Pero los enlaces simbólicos absolutos son problemáticos, ya que apuntan a un objetivo fuera del subsistema de archivos.
Como ejemplo, asumimos un enlace simbólico absoluto de la siguiente manera (visto dentro del subsistema de archivos):
/usr/file1 -> /usr/lib/file1
En el sistema de archivos general tenemos un enlace en /home/user/system/usr/file1
que ahora apuntan a un archivo /usr/lib/file1
fuera del subsistema de archivos, en lugar de un archivo /home/user/system/usr/lib/file1
dentro el subsistema de archivos.
Me gustaría tener un script simple, preferiblemente una sola línea de comando (rsync, chroot, find, …) que convierta cada enlace simbólico absoluto en uno relativo.
En el ejemplo dado, ese vínculo relativo se convertiría en
/usr/file1 -> ../usr/lib/file1
Respuesta aceptada:
Con los symlinks
utilidad de Mark Lord (ofrecida por muchas distribuciones; si la suya no la tiene, constrúyala desde el código fuente):
chroot /home/user/system symlinks -cr .
Alternativamente, en sistemas que tienen un readlink
comando y un -lname
predicado para find
(advertencia:código no probado):
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
' _ {} +