Frecuentemente muevo árboles de directorios a otras ubicaciones o copie sus tarballs a otras máquinas, y me gustaría tener un método para verificar si algún enlace simbólico en un árbol de directorios A apunta a ubicaciones fuera de A ya que estos se romperán en el movido / copiado directorio.
8
Use bindfs para crear otra vista de ese árbol de directorios.
Luego use la utilidad de enlaces simbólicos (enviada por muchas distribuciones, o compílela desde la fuente ) para detectar enlaces entre sistemas de archivos.
(Tenga en cuenta que al analizar la salida se supone que sus enlaces simbólicos y sus objetivos no contienen nuevas líneas, ni las rutas a los enlaces simbólicos contienen la subcadena
->
). Esa misma utilidad también puede convertir enlaces simbólicos absolutos a relativos (pero querrá hacerlo desde La ubicación original).fuente
Con zsh:
Ahora, si el directorio es
/foo
y tiene/foo/bar
un enlace simbólico/foo/baz
, ese es un enlace cuyo objetivo está en / foo, pero una vez movido, el enlace seguirá roto, por lo que es posible que también desee hacer coincidir los enlaces simbólicos con las rutas absolutas.Pero incluso entonces, una
bar => ../foo/baz
en/foo
sería un problema (falso negativo), por lo que sería unaa => b
dondeb
es un enlace simbólico fuera del árbol (falsos positivos, dependiendo de cómo desea que mirarlo)fuente
Tuve que ajustar un poco la respuesta dada por @bahamat para que funcione.
La versión proporcionada simplemente informó la ubicación absoluta ofensiva, pero no el enlace simbólico que apunta a ella.
Esto es lo que usé (estoy seguro de que se puede mejorar):
fuente
for f in $(find . -type l); do echo $(realpath -m -q $f) '<-' $f; done | grep-v "^$(pwd)"
(más notablemente-m
y-q
que filtra los enlaces rotos y no externos)GNU coreutils provedes
realpath
, que resuelve enlaces simbólicos. Con esto, puede comparar el objetivo de cada enlace simbólico con el directorio de trabajo actual con algo como:fuente
-type l
, ninguna-r
opción pararead
, IFS no desinfectadoread
,$filename
no citado,$PWD
tratado como una expresión regular, las rutas con caracteres de nueva línea no contabilizados,/foobar
serían igualadas$PWD
== "/ foo"