Mantengo mis dotfiles bajo control de versiones y el script que los implementa crea enlaces duros. También uso etckeeper
para poner mi /etc
bajo control de versiones. Recientemente recibí advertencias como esta:
warning: hard-linked files could cause problems with bzr
Una copia simple ( cp filename.ext filename.ext
) no funcionará:
cp: `filename.ext' and `filename.ext' are the same file
Cambiar el nombre / mover un archivo, excepto a través de volúmenes, tampoco rompe el enlace duro.
Entonces mi pregunta es: ¿hay alguna manera de romper un enlace duro a un archivo sin tener que saber dónde están los otros enlaces duros a ese archivo?
Respuestas:
Haciéndolo programable:
Hacer la copia primero, luego moverla a su lugar, tiene la ventaja de que el archivo cambia atómicamente de ser un enlace rígido a ser una copia separada (no hay un momento en el que
filename
sea parcial o faltante).fuente
Probablemente quiere decir que quiere dividir el enlace duro en un archivo separado e independiente.
Un enlace duro es la conexión entre una entrada en el directorio y el bloque de inodo en el disco.
los inodes almacenan metadatos de archivos, y para archivos pequeños, algunos sistemas de archivos almacenan datos en el inodo, de lo contrario apuntan a los bloques de datos, y para archivos muy grandes listas indirectas y doble-indirectas de punteros a unidades de asignación de disco.
En cualquier caso, la conexión entre el nombre del archivo (que es lo que produce el comando ls) y el bloque de inodo que almacena estos metadatos, se denomina enlace duro.
Tener múltiples enlaces duros a un solo archivo significa el mismo inodo al que hace referencia más de una entrada de directorio, posiblemente en diferentes directorios (en un solo sistema de archivos)
rm elimina la entrada del nombre del archivo del directorio. Una vez que ningún archivo hace referencia a un inodo, su espacio se libera para que otros archivos lo utilicen.
fuente
cp
ymv
ejemplos implícito. Así que no puedo evitar usar un archivo temporal, ya veo.cp -a
(al menos GNU coreutils).Ponga esto al final de su archivo ~ / .bashrc.
Ejecútalo así
fuente
La mejor manera de hacerlo con un script bash sería algo como esto:
puntos a tener en cuenta:
mktemp
para generar un archivo que se garantiza que no existe-f
para forzar la sobrescritura y--preserve=all
para mantener los metadatos lo más similares posible al archivo original--
y"
para citar rutas que contienen espacios y / o que comienzan con-
Hacer el reemplazo sin crear un archivo temporal no es posible con las llamadas actuales del sistema Linux (3.16): si bien es posible sobrescribir un archivo atómicamente (es decir, eliminar el archivo antiguo y reemplazarlo por uno nuevo como una sola operación), no es posible hacerlo con un archivo que no tiene nombre en el sistema de archivos (es decir, un archivo temporal creado usando el
O_TMPFILE
indicador deopen
función) porque larename
función requiere un nombre de archivo como entrada (no hay una versiónrename
que tome como entrada un descriptor de archivo) ver aquí para más detalles)fuente
dirname
ymktemp
llamadas. Arreglado eso para ti ...$( ... )
sustitución de comandos de estilo. Una razón es mejor que el` ... `
estilo.`
te pongan:`\``
(por supuesto, me escapé de eso para que te muestre lo que escribes).El comando que estás buscando es
unlink
fuente
cp
ymv
quise aclarar que deseo que el archivo exista después.Si está buscando todos los nombres de archivo que están vinculados a este archivo, puede usar:
también
ls -il myknowhardlinkfile
le mostrará el número de nombre de archivo vinculado al mismo inodo (tercer campo).fuente