Qué son los enlaces duros, los enlaces simbólicos (enlaces blandos) y los inodos en Linux. Cómo crear y eliminar enlaces duros y enlaces simbólicos y cómo obtener información sobre el inodo asociado a un fichero. Explicamos cómo buscar ficheros (originales y enlaces duros) por el inodo en Linux.

inodo en Linux

Todo archivo en Linux tiene asociado un número entero llamado inodo. Este identificador numérico es único por cada archivo (no se repite). En Linux, usando el comando ls, puede obtenerse el inodo asignado a cada archivo.

Como ejemplo, crearemos un fichero en Linux, con el siguiente comando:

Introduciremos contenido al fichero creado (fichero.txt), usando el editor nano (o vi):

Introduciremos un contenido de ejemplo y lo guardaremos (pulsando Control + O y Control + X):

Mostramos el contenido del fichero para verificar que se ha guardado, con el comando:

Para consultar el inodo asignado al fichero creado, ejecutaremos el siguiente comando:

El primer valor que muestra el comando es el número asignado de inodo al fichero creado, en este caso el 1572882. También muestra el número de enlaces que tiene el fichero (de momento solo uno, el enlace original al archivo).

Con el siguiente comando podemos obtener también el inodo asignado a un fichero y más información (fechas de acceso, modificación, creación, bloques usados, tamaño, tipo de fichero, gid, etc.:

El comando stat, al igual que el comando ls, muestra tanto el número de inodo asociado al fichero (en la etiqueta Nodo-i), como el número de enlaces (en la etiqueta Enlaces). Como podemos comprobar, el número de enlaces sigue siendo uno, dado que aún no hemos creado enlaces simbólicos ni enlaces duros al fichero.

Enlace duro en Linux

Un enlace duro es una nueva conexión al fichero original. Se le llama «duro» porque una vez creado el enlace duro, aunque se eliminara el fichero original, el fichero creado como enlace duro seguirá manteniendo el contenido del fichero original. Tanto el fichero original como el enlace duro compartirán el mismo inodo.

Para entender esto, lo mejor es utilizar un ejemplo. Con el fichero creado anteriormente «fichero.txt», que está en la carpeta /home/am, se puede comprobar con el comando:

Lo que haremos, desde otra carpeta del equipo, será crear un enlace duro al fichero /home/am/fichero.txt. Para ello, nos situaremos en otra carpeta, por ejemplo en /tmp:

Y crearemos allí el enlace duro, con el siguiente comando:

Listamos los dos ficheros para comprobar que, efectivamente, tienen el mismo inodo:

Y si seguimos observando el resultado de los comandos anteriores, veremos que ahora el número de enlaces del fichero original (y del enlace duro) es de dos:

Si mostramos el contenido del enlace duro, será el mismo que el del fichero original:

Si modificamos el fichero original, también se modificará el enlace duro y viceversa. En realidad, ambos enlaces apuntan al mismo contenido (al mismo inodo). Como ejemplo, vamos a añadir alguna línea al fichero original, mostrar el contenido del original y del enlace duro y repetir el proceso para el enlace duro. Comprobando que cualquier cambio en el fichero original queda en el enlace duro y viceversa:

Ahora vamos a probar a eliminar el fichero original, para comprobar que mientras exista un enlace duro, el contenido no se perderá:

Si volvemos a mostrar el contenido del enlace duro, comprobaremos que sigue existiendo:

Y es que, es muy importante saber que si un fichero tiene un enlace duro (o varios), mientras tenga alguno, aunque se elimine el fichero original, el enlace duro mantendrá su contenido.

Si ahora hacemos un:

Comprobaremos que el enlace duro ahora tiene un solo link (enlace) en lugar de dos. Esto es así porque el enlace duro ha pasado a ser el fichero original.

Por supuesto, si se eliminar el enlace duro y se ha eliminado el fichero original, se perderá definitivamente su contenido.

Para eliminar un enlace duro, se usa el mismo comando que para un fichero «normal»:

De cara al espacio usado por los ficheros originales y los posibles enlaces duros, el espacio será sólo el ocupado por el fichero original, dado que son enlaces al inodo y no duplicaciones de contenido.

Buscar ficheros por el inodo en Linux

Hay que tener en cuenta, en base a la seguridad informática (y a la liberación de espacio), que un atacante podría crear un enlace duro a un fichero (por ejemplo, que contenga datos confidenciales). Si eliminamos el fichero fichero original pensando que no hay enlaces duros, al existir uno (o varios) enlace duro, el contenido del fichero no habría quedado eliminado (como ya hemos indicado y demostrado anteriormente). Por lo tanto el espacio ocupado no se liberará y, además, un posible atacante seguiría teniendo acceso a los datos.

Por lo tanto, antes de eliminar un fichero original, recomendamos comprobar si tiene enlaces duros, con el comando que ya conocemos:

En el fichero de ejemplo, comprobamos que tiene cinco enlaces duros, por lo que hasta que no se elimine el fichero original y los cinco enlaces duros, no se eliminará el contenido definitivamente. Para listar todos los enlaces duros de un fichero original podemos utilizar una búsqueda por inodo, dado que todos comparten el mismo. Para esto, dado que en el comando anterior hemos obtenido el inodo del fichero original, en este caso el 1438998, ejecutaremos el siguiente comando:

Comprobamos que, efectivamente, el comando nos muestra todos los enlaces duros al fichero e incluso el propio fichero original:

Ahora, si queremos eliminar con seguridad el fichero original, eliminaremos también todos los enlaces duros:

Ahora comprobaremos que el fichero original solo tiene un enlace (el suyo propio):

ls -li /home/alonso/mi_fichero.sh

Por lo que ya podremos eliminarlo con seguridad:

Si volvemos a ejecutar en find para buscar por el inodo, no debe devolver nada:

Enlace simbólico o enlace blando en Linux

El enlace simbólico o enlace blando es como un acceso directo. Si se eliminar el fichero original, aunque tenga uno o varios enlaces simbólicos, se eliminará su contenido.

Vamos a crear un fichero de ejemplo, en la carpeta /home/alonso, con el nombre «mi_fichero.sh». Para ello, como en el apartado anterior, usaremos el comando touch:

Le añadimos contenido con cualquier editor, como vi o nano:

Mostramos el contenido para verificar que se ha guardado, con:

Ahora accederemos a otra carpeta, por ejemplo a /tmp:

Y crearemos un enlace simbólico (enlace blando) al fichero anterior. Para ello, ejecutaremos el siguiente comando:

Que habrá creado un fichero llamado «enlace_fichero». Si listamos los dos ficheros (el original y el enlace blando), podremos comprobar que tienen diferente inodo. Esto es así porque Linux, al contrario que en los enlaces duros, los trata como otro fichero diferente:

Además, tampoco se incrementa el número de enlaces para el fichero original, que sin indicando que tiene un único enlace. Otra diferencia, con respecto a los enlaces duros, es que en la máscara donde se indican los permisos y tipo de archivo/directorio, para el enlace simbólico o blando, se le añade una ele (l): lrwxrwxrwx. Otra diferencia es que, por defecto, se le añaden todos los permisos para todos los usuarios. Eso sí, los permisos se añaden al enlace, no al fichero original, que tendrá los propios y serán estos los que prevalezcan.

En el caso de los enlaces simbólicos, si eliminamos el fichero original:

A diferencia de los enlaces duros, el enlace simbólico se romperá y el contenido del fichero habrá desaparecido definitivamente. Si hacemos un cat veremos que nos da error de fichero no encontrado:

Si volvemos a crear un fichero en la misma carpeta con el mismo nombre, el enlace simbólico volverá a funcionar:

Por lo tanto demostramos que el enlace blando o simbólico no enlaza directamente con el inodo del fichero original, sino que lo hace por la ruta y nombre. Dado que en el caso anterior, al eliminar el fichero original y volver a crearlo, el inodo asignado es diferente, es un fichero totalmente nuevo (aunque tuviera el mismo nombre y contenido) y el enlace simbólico se ha corregido. En cambio, el enlace duro sí enlaza directamente con el inodo del fichero original, comparten el mismo inodo.