Corro
ln /a/A /b/B
Me gustaría ver en la carpeta adonde están los puntos a presentar una por ls.
Corro
ln /a/A /b/B
Me gustaría ver en la carpeta adonde están los puntos a presentar una por ls.
Respuestas:
Puede encontrar el número de inodo para su archivo con
ls -i
y
ls -l
muestra el recuento de referencias (número de enlaces duros a un inodo particular)
Después de encontrar el número de inodo, puede buscar todos los archivos con el mismo inodo:
find . -inum NUM
mostrará los nombres de archivo para inode NUM en el directorio actual (.)
Realmente no hay una respuesta bien definida a su pregunta. A diferencia de los enlaces simbólicos, los enlaces duros no se pueden distinguir del "archivo original".
Las entradas de directorio consisten en un nombre de archivo y un puntero a un inodo. El inodo a su vez contiene los metadatos del archivo y (apunta a) el contenido real del archivo). Crear un enlace duro crea otro nombre de archivo + referencia al mismo inodo. Estas referencias son unidireccionales (al menos en sistemas de archivos típicos): el inodo solo mantiene un recuento de referencias. No hay una forma intrínseca de averiguar cuál es el nombre de archivo "original".
Por cierto, esta es la razón por la cual se llama al sistema para "eliminar" un archivo unlink. Simplemente elimina un enlace duro. El inodo y los datos adjuntos se eliminan solo si el recuento de referencia del inodo cae a 0.
La única forma de encontrar las otras referencias a un inodo dado es buscar exhaustivamente en el sistema de archivos comprobando qué archivos se refieren al inodo en cuestión. Puede usar 'prueba A -ef B' desde el shell para realizar esta verificación.
UNIX tiene enlaces duros y enlaces simbólicos (hechos con "ln"y "ln -s"respectivamente). Los enlaces simbólicos son simplemente un archivo que contiene la ruta real a otro archivo y puede cruzar sistemas de archivos.
Los enlaces duros han existido desde los primeros días de UNIX (que puedo recordar de todos modos, y eso se remonta bastante tiempo). Son dos entradas de directorio que hacen referencia a los exactos mismos datos subyacentes. Los datos en un archivo se especifican por su inode. Cada archivo en un sistema de archivos apunta a un inodo, pero no es necesario que cada archivo apunte a un inodo único, de ahí provienen los enlaces duros.
Dado que los inodos son únicos solo para un sistema de archivos dado, existe una limitación de que los enlaces duros deben estar en el mismo sistema de archivos (a diferencia de los enlaces simbólicos). Tenga en cuenta que, a diferencia de los enlaces simbólicos, no hay un archivo privilegiado, todos son iguales. El área de datos solo se liberará cuando se eliminen todos los archivos que usan ese inodo (y todos los procesos también lo cierran, pero ese es un problema diferente).
Puede usar el "ls -i"comando para obtener el inodo de un archivo en particular. Luego puede usar el "find <filesystemroot> -inum <inode>"comando para buscar todos los archivos en el sistema de archivos con ese inodo dado.
Aquí hay un script que hace exactamente eso. Lo invocas con:
findhardlinks ~/jquery.js
y encontrará todos los archivos en ese sistema de archivos que son enlaces duros para ese archivo:
pax@daemonspawn:~# ./findhardlinks /home/pax/jquery.js
Processing '/home/pax/jquery.js'
'/home/pax/jquery.js' has inode 5211995 on mount point '/'
/home/common/jquery-1.2.6.min.js
/home/pax/jquery.js
Aquí está el guión.
#!/bin/bash
if [[ $# -lt 1 ]] ; then
echo "Usage: findhardlinks <fileOrDirToFindFor> ..."
exit 1
fi
while [[ $# -ge 1 ]] ; do
echo "Processing '$1'"
if [[ ! -r "$1" ]] ; then
echo " '$1' is not accessible"
else
numlinks=$(ls -ld "$1" | awk '{print $2}')
inode=$(ls -id "$1" | awk '{print $1}' | head -1l)
device=$(df "$1" | tail -1l | awk '{print $6}')
echo " '$1' has inode ${inode} on mount point '${device}'"
find ${device} -inum ${inode} 2>/dev/null | sed 's/^/ /'
fi
shift
done
. ./findhardlinks.bashmientras estoy en Zsh de OS X. Mi ventana actual en la pantalla se cierra.
INUM=$(stat -c %i $1). También NUM_LINKS=$(stat -c %h $1). Consulte man statpara ver más variables de formato que puede usar.
ls -l
La primera columna representará los permisos. La segunda columna será el número de subelementos (para directorios) o el número de rutas a los mismos datos (enlaces duros, incluido el archivo original) al archivo. P.ej:
-rw-r--r--@ 2 [username] [group] [timestamp] HardLink
-rw-r--r--@ 2 [username] [group] [timestamp] Original
^ Number of hard links to the data
inodeque a su vez apunta al contenido del disco.
¿Qué tal el siguiente más simple? (¡Este último podría reemplazar los largos guiones de arriba!)
Si tiene un archivo específico <THEFILENAME>y desea conocer todos sus enlaces rígidos distribuidos en el directorio <TARGETDIR>(que incluso puede ser todo el sistema de archivos indicado por /)
find <TARGETDIR> -type f -samefile <THEFILENAME>
Extendiendo la lógica, si desea conocer todos los archivos que <SOURCEDIR>tienen múltiples enlaces duros distribuidos en <TARGETDIR>:
find <SOURCEDIR> -type f -links +1 \
-printf "\n\n %n HardLinks of file : %H/%f \n" \
-exec find <TARGETDIR> -type f -samefile {} \;
-type fporque el archivo también puede ser un directorio.
.y ..en los directorios son enlaces duros. Puede saber cuántos subdirectores hay en un directorio a partir del recuento de enlaces de .. Esto es discutible de todos modos, ya que find -samefile .todavía no imprimirá ningún subdir/..resultado. find(al menos la versión GNU) parece ser difícil de ignorar .., incluso con -noleaf.
O(n^2), y se ejecuta finduna vez para cada miembro de un conjunto de archivos vinculados. find ... -printf '%16i %p\n' | sort -n | uniq -w 16 --all-repeated=separatefuncionaría, (16 no es lo suficientemente ancho para una representación decimal de 2 ^ 63-1, por lo que cuando su sistema de archivos XFS es lo suficientemente grande como para tener números de inodo tan altos, tenga cuidado)
Hay muchas respuestas con scripts para encontrar todos los enlaces duros en un sistema de archivos. La mayoría de ellos hacen cosas tontas como ejecutar find para escanear todo el sistema de archivos en -samefilebusca de CADA archivo con enlaces múltiples. Esto es Loco; todo lo que necesita es ordenar el número de inodo e imprimir duplicados.
Con solo una pasada sobre el sistema de archivos para buscar y agrupar todos los conjuntos de archivos enlazados
find dirs -xdev \! -type d -links +1 -printf '%20D %20i %p\n' |
sort -n | uniq -w 42 --all-repeated=separate
Esto es mucho más rápido que las otras respuestas para encontrar múltiples conjuntos de archivos enlazados.
find /foo -samefile /bares excelente para solo un archivo.
-xdev: límite a un sistema de archivos. No es estrictamente necesario ya que también imprimimos el FS-id para uniq en! -type drechazar directorios: las entradas .y ..significan que siempre están vinculados.-links +1 : enlace cuenta estrictamente > 1-printf ...imprime FS-id, número de inodo y ruta. (Con relleno para anchos de columna fijos de los que podemos hablar uniq).sort -n | uniq ... ordenación numérica y uniquificación en las primeras 42 columnas, separando grupos con una línea en blancoEl uso ! -type d -links +1significa que la entrada de clasificación es tan grande como la salida final de uniq, por lo que no estamos haciendo una gran cantidad de clasificación de cadenas. A menos que lo ejecute en un subdirectorio que solo contiene uno de un conjunto de enlaces duros. De todos modos, esto usará MUCHO menos tiempo de CPU para volver a recorrer el sistema de archivos que cualquier otra solución publicada.
salida de muestra:
...
2429 76732484 /home/peter/weird-filenames/test/.hiddendir/foo bar
2429 76732484 /home/peter/weird-filenames/test.orig/.hiddendir/foo bar
2430 17961006 /usr/bin/pkg-config.real
2430 17961006 /usr/bin/x86_64-pc-linux-gnu-pkg-config
2430 36646920 /usr/lib/i386-linux-gnu/dri/i915_dri.so
2430 36646920 /usr/lib/i386-linux-gnu/dri/i965_dri.so
2430 36646920 /usr/lib/i386-linux-gnu/dri/nouveau_vieux_dri.so
2430 36646920 /usr/lib/i386-linux-gnu/dri/r200_dri.so
2430 36646920 /usr/lib/i386-linux-gnu/dri/radeon_dri.so
...
TODO ?: descomprime la salida con awko cut. uniqtiene un soporte de selección de campo muy limitado, por lo que relleno la salida de búsqueda y uso ancho fijo. 20 caracteres es lo suficientemente ancho para el máximo número posible de inodo o dispositivo (2 ^ 64-1 = 18446744073709551615). XFS elige los números de inodo según el lugar del disco en el que están asignados, no contiguamente desde 0, por lo que los sistemas de archivos XFS grandes pueden tener números de inodo> 32 bits incluso si no tienen miles de millones de archivos. Otros sistemas de archivos pueden tener números de inodo de 20 dígitos, incluso si no son gigantes.
TODO: ordena los grupos de duplicados por ruta. Tenerlos ordenados por punto de montaje y luego número de inodo mezcla cosas juntas, si tiene un par de subdirecciones diferentes que tienen muchos enlaces duros. (es decir, grupos de grupos dobles van juntos, pero la salida los mezcla).
Una final sort -k 3ordenaría las líneas por separado, no grupos de líneas como un solo registro. El preprocesamiento con algo para transformar un par de líneas nuevas en un byte NUL, y el uso de GNU sort --zero-terminated -k 3podría ser el truco. trSin embargo, solo funciona con caracteres individuales, no con patrones 2-> 1 o 1-> 2. perllo haría (o simplemente analizar y ordenar dentro de perl o awk). sedTambién podría funcionar.
%Des el identificador de sistema de archivos (que es único para el inicio actual, mientras que no hay sistemas de ficheros se umounted), por lo siguiente es incluso más genérica: find directories.. -xdev ! -type d -links +1 -printf '%20i %20D %p\n' | sort -n | uniq -w 42 --all-repeated=separate. Esto funciona siempre que ningún directorio dado contenga otro directorio en el nivel del sistema de archivos, también analiza todo lo que se puede vincular (como dispositivos o enlaces programables; sí, los enlaces programables pueden tener un recuento de enlaces mayor que 1). Tenga en cuenta que dev_ty ino_ttiene 64 bits de largo hoy. Esto probablemente se mantendrá mientras tengamos sistemas de 64 bits.
! -type d, en lugar de -type f. Incluso tengo algunos enlaces simbólicos enlazados en mi sistema de archivos por organizar algunas colecciones de archivos. Actualicé mi respuesta con su versión mejorada (pero puse el id de fs primero, por lo que el orden de clasificación al menos se agrupa por sistema de archivos)
Esto es algo así como un comentario a la propia respuesta y guión de Torocoro-Macho, pero obviamente no cabe en el cuadro de comentarios.
Reescribió su script con formas más directas de encontrar la información y, por lo tanto, muchas menos invocaciones de proceso.
#!/bin/sh
xPATH=$(readlink -f -- "${1}")
for xFILE in "${xPATH}"/*; do
[ -d "${xFILE}" ] && continue
[ ! -r "${xFILE}" ] && printf '"%s" is not readable.\n' "${xFILE}" 1>&2 && continue
nLINKS=$(stat -c%h "${xFILE}")
if [ ${nLINKS} -gt 1 ]; then
iNODE=$(stat -c%i "${xFILE}")
xDEVICE=$(stat -c%m "${xFILE}")
printf '\nItem: %s[%d] = %s\n' "${xDEVICE}" "${iNODE}" "${xFILE}";
find "${xDEVICE}" -inum ${iNODE} -not -path "${xFILE}" -printf ' -> %p\n' 2>/dev/null
fi
done
Traté de mantenerlo lo más similar posible al suyo para facilitar la comparación.
Uno siempre debe evitar la $IFSmagia si un globo es suficiente, ya que es innecesariamente complicado, y los nombres de los archivos pueden contener nuevas líneas (pero en la práctica, principalmente, la primera razón).
Debe evitar el análisis manual lsy la salida de este tipo tanto como sea posible, ya que tarde o temprano lo morderá. Por ejemplo: en su primera awklínea, falla en todos los nombres de archivos que contienen espacios.
printfa menudo ahorrará problemas al final ya que es muy robusto con la %ssintaxis. También le brinda control total sobre la salida, y es consistente en todos los sistemas, a diferencia echo.
stat puede ahorrarle mucha lógica en este caso.
GNU find es poderoso
Sus invocaciones heady tailpodrían haberse manejado directamente awkcon, por ejemplo, el exitcomando y / o la selección en la NRvariable. Esto ahorraría invocaciones de procesos, que casi siempre mejoran severamente el rendimiento en scripts de trabajo duro.
Tu egreps bien podría ser justo grep.
find ... -xdev -type f -links +1 -printf '%16i %p\n' | sort -n | uniq -w 16 --all-repeated=separate. Esto es MUCHO más rápido, ya que solo atraviesa el fs una vez. Para múltiples FSes a la vez, necesitará prefijar los números de inodo con una identificación FS. Quizás confind -exec stat... -printf ...
Basado en el findhardlinksscript (renombrado como hard-links), esto es lo que he refactorizado y lo hice funcionar.
Salida:
# ./hard-links /root
Item: /[10145] = /root/.profile
-> /proc/907/sched
-> /<some-where>/.profile
Item: /[10144] = /root/.tested
-> /proc/907/limits
-> /<some-where else>/.bashrc
-> /root/.testlnk
Item: /[10144] = /root/.testlnk
-> /proc/907/limits
-> /<another-place else>/.bashrc
-> /root/.tested
# cat ./hard-links
#!/bin/bash
oIFS="${IFS}"; IFS=$'\n';
xPATH="${1}";
xFILES="`ls -al ${xPATH}|egrep "^-"|awk '{print $9}'`";
for xFILE in ${xFILES[@]}; do
xITEM="${xPATH}/${xFILE}";
if [[ ! -r "${xITEM}" ]] ; then
echo "Path: '${xITEM}' is not accessible! ";
else
nLINKS=$(ls -ld "${xITEM}" | awk '{print $2}')
if [ ${nLINKS} -gt 1 ]; then
iNODE=$(ls -id "${xITEM}" | awk '{print $1}' | head -1l)
xDEVICE=$(df "${xITEM}" | tail -1l | awk '{print $6}')
echo -e "\nItem: ${xDEVICE}[$iNODE] = ${xITEM}";
find ${xDEVICE} -inum ${iNODE} 2>/dev/null|egrep -v "${xITEM}"|sed 's/^/ -> /';
fi
fi
done
IFS="${oIFS}"; echo "";
Una solución GUI se acerca mucho a su pregunta:
No puede enumerar los archivos vinculados reales de "ls" porque, como han señalado los comentaristas anteriores, los "nombres" de los archivos son meros alias de los mismos datos. Sin embargo, en realidad hay una herramienta GUI que se acerca mucho a lo que desea, que es mostrar una lista de rutas de nombres de archivos que apuntan a los mismos datos (como enlaces duros) en Linux, se llama FSLint. La opción que desea está en "Choques de nombres" -> deseleccione "casilla de verificación $ RUTA" en Buscar (XX) -> y seleccione "Alias" en el cuadro desplegable después de "para ..." hacia la parte superior central.
FSLint está muy poco documentado, pero descubrí que asegurándose de que el árbol de directorios limitado en "Ruta de búsqueda" con la casilla de verificación seleccionada para "¿Recurrir?" y las opciones antes mencionadas, una lista de datos vinculados con rutas y nombres que "apuntan" a los mismos datos se producen después de las búsquedas del programa.
Puede configurar lspara resaltar los enlaces duros usando un 'alias', pero como se indicó anteriormente, no hay forma de mostrar la 'fuente' del enlace duro, por lo que anexo .hardlinkayuda con eso.
Agregue lo siguiente en algún lugar de su .bashrc
alias ll='LC_COLLATE=C LS_COLORS="$LS_COLORS:mh=1;37" ls -lA --si --group-directories-first'
link(2)llamada al sistema, no tiene sentido cuál es el original y el enlace. Por eso, como señalan las respuestas, la única forma de encontrar todos los enlaces esfind / -samefile /a/A. Porque una entrada de directorio para un inodo no "conoce" otras entradas de directorio para el mismo inodo. Todo lo que hacen es volver a contar el inodo para que se pueda eliminar cuando el apellido esunlink(2)ed. (Este es el "conteo de enlaces" en lalssalida).