soporta - Linux: ¿encuentra todos los enlaces simbólicos de un archivo ''original'' dado?(reverse ''readlink'')
no se permiten enlaces fuertes para directorios (6)
Esto es lo que se me ocurrió. Estoy haciendo esto en OS X, que no tiene readlink -f
, así que tuve que usar una función auxiliar para reemplazarlo. Si lo tiene un readlink -f
apropiado readlink -f
puede usarlo en su lugar. Además, el uso de while ... done < <(find ...)
no es estrictamente necesario en este caso, un simple find ... | while ... done
find ... | while ... done
funcionaría; pero si alguna vez quisiste hacer algo como establecer una variable dentro del ciclo (como un recuento de archivos que coincidan), la versión de la tubería fallaría porque el ciclo while se ejecutaría en una subcadena. Finalmente, nótese que uso find ... -type l
para que el loop solo se ejecute en enlaces simbólicos, no en otros tipos de archivos.
# Helper function ''cause my system doesn''t have readlink -f
readlink-f() {
orig_dir="$(pwd)"
f="$1"
while [[ -L "$f" ]]; do
cd "$(dirname "$f")"
f="$(readlink "$(basename "$f")")"
done
cd "$(dirname "$f")"
printf "%s/n" "$(pwd)/$(basename "$f")"
cd "$orig_dir"
}
target_file="$(readlink-f "$target_file")" # make sure target is normalized
while IFS= read -d '''' linkfile; do
if [[ "$(readlink-f "$linkfile")" == "$target_file" ]]; then
printf "%s/n" "$linkfile"
fi
done < <(find "$search_dir" -type l -print0)
Considere el siguiente fragmento de línea de comando:
$ cd /tmp/
$ mkdir dirA
$ mkdir dirB
$ echo "the contents of the ''original'' file" > orig.file
$ ls -la orig.file
-rw-r--r-- 1 $USER $USER 36 2010-12-26 00:57 orig.file
# create symlinks in dirA and dirB that point to /tmp/orig.file:
$ ln -s $(pwd)/orig.file $(pwd)/dirA/
$ ln -s $(pwd)/orig.file $(pwd)/dirB/lorig.file
$ ls -la dirA/ dirB/
dirA/:
total 44
drwxr-xr-x 2 $USER $USER 4096 2010-12-26 00:57 .
drwxrwxrwt 20 root root 36864 2010-12-26 00:57 ..
lrwxrwxrwx 1 $USER $USER 14 2010-12-26 00:57 orig.file -> /tmp/orig.file
dirB/:
total 44
drwxr-xr-x 2 $USER $USER 4096 2010-12-26 00:58 .
drwxrwxrwt 20 root root 36864 2010-12-26 00:57 ..
lrwxrwxrwx 1 $USER $USER 14 2010-12-26 00:58 lorig.file -> /tmp/orig.file
En este punto, puedo usar readlink
para ver cuál es el ''original'' (bueno, supongo que el término usual aquí es ''objetivo'' o ''fuente'', pero esos en mi mente también pueden ser conceptos opuestos, entonces yo '' ll simplemente llámalo ''original'') archivo de los enlaces simbólicos, es decir,
$ readlink -f dirA/orig.file
/tmp/orig.file
$ readlink -f dirB/lorig.file
/tmp/orig.file
... Sin embargo, lo que me gustaría saber es: ¿hay algún comando que pueda ejecutar en el archivo ''original'' y encuentre todos los enlaces simbólicos que lo señalen? En otras palabras, algo como (pseudo):
$ getsymlinks /tmp/orig.file
/tmp/dirA/orig.file
/tmp/dirB/lorig.file
Gracias de antemano por cualquier comentario,
¡Aclamaciones!
Esto puede ser demasiado simplista para lo que quiere hacer, pero lo encuentro útil. No responde su pregunta literalmente, ya que no se ''ejecuta en el archivo original'', pero cumple la tarea. Pero, mucho más acceso a HDD. Y, solo funciona para archivos vinculados "suaves" que es la mayoría de los archivos vinculados por el usuario.
desde la raíz de su directorio de almacenamiento de datos o los directorios de datos de los usuarios, donde puedan residir los "archivos" orig.file
al orig.file
, ejecute el comando find:
# find -type l -ls |grep -i ''orig.file''
o
# find /Starting/Search/ Path/ -type l -ls |grep -i ''*orig*''
Normalmente usaría parte del nombre, por ejemplo, ''*orig*''
para comenzar, porque sabemos que los usuarios cambiarán el nombre (prefijo) de un archivo de nombre simple por uno más descriptivo como "Informe de enero de London _ orig.file.2015.01.21 " o algo.
Nota: Nunca he obtenido la opción -mearchivo para que funcione para mí.
limpio, simple, fácil de recordar
Espero que esto ayude a alguien. Landis.
Inspirado por el comentario de Gordon Davisson. Esto es similar a otra respuesta, pero obtuve los resultados deseados utilizando el comando ejecutivo. Necesitaba algo que pudiera encontrar enlaces simbólicos sin saber dónde estaba ubicado el archivo original.
find / -type l -exec ls -al {} /; | grep -i "all_or_part_of_original_name"
Los enlaces simbólicos no rastrean lo que está apuntando a un destino dado, por lo que no puede hacer más que verificar cada enlace simbólico para ver si apunta al destino deseado, como
for i in *; do
if [ -L "$i" ] && [ "$i" -ef /tmp/orig.file ]; then
printf "Found: %s/n" "$i"
fi
done
No he visto un comando para esto y no es una tarea fácil, ya que el archivo de destino no contiene información sobre qué archivos fuente lo señalan.
Esto es similar a los enlaces "duros", pero al menos esos están siempre en el mismo sistema de archivos, por lo que puede hacer un find -inode
para find -inode
. Los enlaces suaves son más problemáticos ya que pueden cruzar sistemas de archivos.
Creo que lo que vas a tener que hacer es básicamente realizar un ls -al
en cada archivo en toda tu jerarquía y usar grep
para buscar -> /path/to/target/file
.
Por ejemplo, aquí hay uno que ejecuté en mi sistema (formateado para ser legible, esas dos últimas líneas están realmente en una línea en la salida real):
pax$ find / -exec ls -ald {} '';'' 2>/dev/null | grep ''/-> /usr/share/applications''
lrwxrwxrwx 1 pax pax 23 2010-06-12 14:56 /home/pax/applications_usr_share
-> /usr/share/applications
Usando GNU find
, encontrará los archivos que están enlazados o vinculados a un archivo:
find -L /dir/to/start -samefile /tmp/orig.file