← Terminal y Línea de Comandos en Linux Bloque 8 · Paquetes y estado del sistema · Tema 38 de 43

Tema 38

Discos y espacio

Un disco lleno no avisa que está lleno. Avisa de otras maneras: un programa que no guarda, una actualización que falla a la mitad, una sesión gráfica que no inicia, un servicio que se detiene sin explicación. De los recursos del sistema es el que más se descuida, porque se agota despacio, y el que produce los síntomas más engañosos. Este tema responde tres preguntas —qué discos hay, cuánto espacio queda, quién lo ocupa— y salda dos deudas viejas: la del tema 7, que prometió explicar cuánto pesa de verdad un directorio, y la del tema 6, que dejó pendiente cómo es que un segundo disco aparece dentro de un árbol único.

1. Disco, partición, sistema de archivos, montaje

Entre el aparato físico y el directorio en que se guardan los archivos hay cuatro niveles. Los nombramos todos en temas anteriores; conviene verlos juntos, porque cada comando de este tema trabaja sobre uno distinto.

NivelQué esEjemplo
DiscoEl dispositivo de almacenamiento: un disco rígido, una unidad de estado sólido, una memoria USB./dev/sda
ParticiónUna porción del disco, que el sistema trata como si fuera un dispositivo independiente./dev/sda2
Sistema de archivosLa organización que se graba en una partición para poder guardar en ella archivos y directorios: sus inodos, sus bloques de datos, sus listas de nombres.ext4
Punto de montajeEl directorio del árbol en el que se hace visible el contenido de un sistema de archivos./
El disco sda está dividido en dos particiones: sda1, pequeña, con un sistema de archivos vfat montado en /boot/efi; y sda2, que ocupa casi todo el disco, con un sistema de archivos ext4 montado en la raíz El disco /dev/sda · 238,5 G sda1 1 G sda2 237,4 G sistema de archivos vfat /boot/efi sistema de archivos ext4 / montado en… el punto de montaje
Un disco, dos particiones, dos sistemas de archivos, dos puntos de montaje. Lo que se ve al listar / es el contenido de sda2.

El sistema de archivos es el nivel que suele pasarse por alto. Una partición recién creada es espacio en bruto; darle un sistema de archivos es lo que comúnmente se llama formatear. Hay varios, y se los reconoce por su nombre en la salida de los comandos:

Sistema de archivosDónde se lo encuentra
ext4El habitual de Linux: la partición del sistema en Ubuntu y Debian.
xfs, btrfsLos que usan por defecto Red Hat y Fedora, respectivamente.
vfat, exfatLos de las memorias USB y tarjetas, legibles por todos los sistemas operativos. No guardan dueños ni permisos.
ntfsEl de Windows. Linux lo lee y lo escribe.
iso9660El de los discos ópticos y las imágenes .iso. De solo lectura.
squashfsComprimido y de solo lectura: el de los paquetes snap del tema 36.
tmpfsReside en la memoria, no en un disco. Lo que se guarda en él se pierde al apagar.
nfs, cifsCarpetas de red: de otro Linux, o de Windows.
Este tema consulta y monta; no particiona ni formatea

Todo lo que haremos es inofensivo para los datos: mirar, medir, montar y desmontar. Crear particiones y sistemas de archivos, con fdisk, parted y mkfs, es otra clase de operación. Se hace como root, sobre un nombre de dispositivo, y destruye en un instante todo lo que hubiera, sin pregunta: es la advertencia sobre /dev/sda del tema 8. Si un tutorial te lleva a esos comandos, verifica tres veces el nombre del dispositivo con el lsblk de la sección siguiente antes de pulsar Enter.

2. lsblk: qué dispositivos hay

lsblk, de list block devices, muestra los discos y sus particiones en forma de árbol. Es el comando para saber qué hay conectado y cómo se llama.

terminal
$ lsblk
NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINTS
loop0    7:0    0     4K  1 loop /snap/bare/5
loop1    7:1    0  73,9M  1 loop /snap/core22/2139
loop2    7:2    0 251,4M  1 loop /snap/firefox/7024
loop3    7:3    0   516M  1 loop /snap/gnome-42-2204/202
loop4    7:4    0  91,7M  1 loop /snap/gtk-common-themes/1535
loop5    7:5    0  10,8M  1 loop /snap/snap-store/1270
loop6    7:6    0  50,8M  1 loop /snap/snapd/25202
sda      8:0    0 238,5G  0 disk
├─sda1   8:1    0     1G  0 part /boot/efi
└─sda2   8:2    0 237,4G  0 part /
ColumnaContiene
NAMEEl nombre del dispositivo. Su archivo está en /dev: sda2 es /dev/sda2.
MAJ:MINLos dos números con que el kernel identifica al dispositivo: los mismos que mostraba ls -l /dev/sda en el tema 7.
RM1 si es extraíble: una memoria USB, una tarjeta.
SIZEEl tamaño del dispositivo.
RO1 si es de solo lectura.
TYPEdisk, un disco entero; part, una partición; loop, un archivo que se usa como si fuera un disco; rom, una lectora óptica.
MOUNTPOINTSDónde está montado. Vacío, si no lo está.

Las siete primeras líneas son la consecuencia que anticipamos en el tema 36: cada snap instalado es un archivo montado como un pequeño disco de solo lectura, y por eso figura como dispositivo loop. No son discos, y estorban. Todos comparten el número mayor 7, y lsblk permite excluir por ese número:

terminal
$ lsblk -e 7
NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINTS
sda      8:0    0 238,5G  0 disk
├─sda1   8:1    0     1G  0 part /boot/efi
└─sda2   8:2    0 237,4G  0 part /
$ lsblk -e 7 -o NAME,FSTYPE,LABEL,UUID,MOUNTPOINTS
NAME   FSTYPE LABEL UUID                                 MOUNTPOINTS
sda
├─sda1 vfat         6C1A-9F3E                            /boot/efi
└─sda2 ext4         3b8f2c6e-71d4-4a0b-9c55-0e2f7a91d6b3 /

Con -o se eligen las columnas. La segunda forma agrega los datos del nivel siguiente: el tipo de sistema de archivos, su etiqueta —un nombre que se le puede dar, y que aquí nadie puso— y su UUID, un identificador único que se genera al formatear. Volveremos a él en la sección 13. lsblk -f muestra una selección parecida sin tener que enumerarla.

Los nombres siguen las convenciones del tema 8, según la clase de dispositivo:

DiscoSus particionesEs
sda, sdb, sdc…sda1, sda2…Discos SATA y USB, en el orden en que se detectaron.
nvme0n1, nvme1n1…nvme0n1p1, nvme0n1p2…Unidades de estado sólido NVMe.
mmcblk0mmcblk0p1…Tarjetas SD y almacenamiento interno de placas pequeñas.
vda, xvdavda1…Discos de máquinas virtuales.

La letra de los sd no es fija. Una memoria USB será sdb hoy y quizá sdc mañana, si se conecta después de otra. Por eso el nombre se averigua cada vez, con lsblk, y nunca se da por sabido.

3. df: cuánto espacio queda

df, de disk free, informa el espacio total, usado y libre de cada sistema de archivos montado. Como free, se usa casi siempre con -h.

terminal
$ df -h
Filesystem      Size  Used Avail Use% Mounted on
tmpfs           784M  2,1M  782M   1% /run
/dev/sda2       233G   61G  161G  28% /
tmpfs           3,9G   48M  3,8G   2% /dev/shm
tmpfs           5,0M  8,0K  5,0M   1% /run/lock
/dev/loop1       74M   74M     0 100% /snap/core22/2139
/dev/loop2      252M  252M     0 100% /snap/firefox/7024
…
/dev/sda1       1,1G  6,2M  1,1G   1% /boot/efi
tmpfs           784M  128K  784M   1% /run/user/1000
ColumnaContiene
FilesystemEl dispositivo, o el tipo si no hay un dispositivo detrás.
SizeLa capacidad del sistema de archivos.
UsedLo ocupado.
AvailLo que un usuario común todavía puede escribir.
Use%El porcentaje ocupado. Es la columna que se vigila.
Mounted onEl punto de montaje.

De todas las líneas, en este equipo importa una: la resaltada. Las demás son ruido que hay que aprender a reconocer, y que df permite quitar excluyendo por tipo, con -x:

terminal
$ df -h -x tmpfs -x squashfs -x efivarfs
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda2       233G   61G  161G  28% /
/dev/sda1       1,1G  6,2M  1,1G   1% /boot/efi
$ df -hT /
Filesystem     Type  Size  Used Avail Use% Mounted on
/dev/sda2      ext4  233G   61G  161G  28% /

Las versiones recientes de df omiten por su cuenta parte de ese ruido; si en tu sistema no aparecen las líneas loop, tanto mejor. Una línea así es un buen candidato para el alias del tema 5, o para el .bashrc del tema 34.

OpciónEfecto
-hUnidades legibles, en potencias de 1024. -H, en potencias de 1000, como las usan los fabricantes de discos.
-TAgrega la columna del tipo de sistema de archivos.
-x tipoExcluye un tipo. Se puede repetir.
-t tipoMuestra solo ese tipo: df -h -t ext4.
-iMuestra inodos en lugar de espacio. Sección 4.
--totalAgrega una línea con la suma.
df rutaMuestra solo el sistema de archivos al que pertenece esa ruta.

La última forma es la más útil y la menos conocida. A df se le puede dar cualquier archivo o directorio, y responde con el sistema de archivos que lo contiene:

terminal
$ df -h ~/practica
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda2       233G   61G  161G  28% /
$ df -h /tmp /dev/shm /boot/efi
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda2       233G   61G  161G  28% /
tmpfs           3,9G   48M  3,8G   2% /dev/shm
/dev/sda1       1,1G  6,2M  1,1G   1% /boot/efi
$ df -h .                              # «¿cuánto lugar hay donde estoy parado?»

Responde de una vez dos preguntas: en qué disco está realmente un directorio, y cuánto lugar queda allí. Antes de copiar algo grande, df -h . es la verificación que evita quedarse a mitad de camino.

4. Leer df sin equivocarse

Tres detalles de esa salida confunden a quien la mira por primera vez.

Los sistemas de archivos que no son discos

Las líneas tmpfs no ocupan nada del disco: son directorios que viven en la memoria. /run guarda datos de los programas en ejecución, y /dev/shm es el que usamos en el tema 14 como ejemplo de «otro sistema de archivos». Su tamaño es un tope, no una reserva: solo consumen la memoria de lo que contienen. Y las líneas loop de los snaps muestran 100% porque un sistema de archivos de solo lectura está, por definición, completo. No es una alarma.

Las cuentas que no cierran

En la línea de sda2, 61 usados más 161 disponibles dan 222, no 233. Y la partición, según lsblk, medía 237,4. Las dos diferencias tienen explicación:

DiferenciaAdónde fue
De 237,4 G de partición a 233 G de capacidad.A las estructuras del propio sistema de archivos: las tablas de inodos y su contabilidad interna.
De 233 G de capacidad a 222 G entre usado y disponible.A la reserva para root: ext4 aparta un 5 % que los usuarios comunes no pueden ocupar.

La reserva tiene un propósito. Cuando un usuario o un programa llenan el disco, a root y a los servicios del sistema les queda todavía un margen para seguir funcionando, iniciar sesión y hacer limpieza. Por eso Use% se calcula sobre lo que un usuario común puede usar, y un disco puede marcar 100% con espacio que solo root ve.

Los inodos también se agotan

En el tema 14 vimos que cada archivo necesita un inodo, y que los inodos están en una tabla del sistema de archivos. En ext4 esa tabla tiene un tamaño fijo, decidido al formatear. Se puede, entonces, quedar sin inodos teniendo espacio de sobra:

terminal
$ df -i /
Filesystem       Inodes  IUsed    IFree IUse% Mounted on
/dev/sda2      15564800 412683 15152117    3% /

Quince millones y medio de inodos, de los que hay en uso cuatrocientos mil: este equipo está lejos. El problema aparece en servidores donde algún programa crea millones de archivos diminutos —sesiones, cachés, correos en cola— y nadie los borra. El síntoma es desconcertante: No space left on device al crear un archivo, mientras df -h muestra gigabytes libres. Ante ese mensaje, la segunda verificación es siempre df -i.

5. du: cuánto ocupa un directorio

df dice cuánto hay ocupado, pero no por quién. La pregunta inversa —cuánto pesa este directorio— la responde du, de disk usage, que recorre un directorio y suma lo que ocupa cada archivo que encuentra.

terminal, en ~/practica
$ cd ~/practica
$ ls -ld fotos
drwxrwxr-x 2 ana ana 4096 oct  3 18:20 fotos
$ du -sh fotos
836K	fotos
$ du -sh .
1,2M	.

Es la respuesta que quedó pendiente en el tema 7. Los 4096 bytes que muestra ls -l son lo que ocupa el directorio en sí, su lista de nombres; du informa lo que ocupa con todo lo que tiene dentro. Sin opciones, du escribe una línea por cada subdirectorio, en bloques de un kibibyte, lo que rara vez se quiere. Las dos letras de -sh lo arreglan:

OpciónEfecto
-sResumen: una sola línea con el total de cada argumento.
-hUnidades legibles.
-aLista también los archivos, no solo los directorios.
-d N, --max-depth=NDetalla hasta N niveles de profundidad. -d 0 equivale a -s.
-cAgrega al final una línea con el total general.
-xNo sale del sistema de archivos de partida: ignora lo que esté montado dentro.
--exclude='patrón'Omite lo que coincida con el patrón.
--apparent-sizeSuma el tamaño de los archivos, en lugar del espacio que ocupan. Sección 7.
--inodesCuenta archivos en lugar de espacio.

Con varios argumentos, o con un comodín, da un total por cada uno. Es la forma de comparar los contenidos de un directorio:

terminal
$ du -sh ~/Descargas ~/Vídeos ~/practica
12G	/home/ana/Descargas
23G	/home/ana/Vídeos
1,2M	/home/ana/practica
$ du -sch *.txt | tail -n 1             # cuánto suman los .txt de aquí
56K	total

Dos advertencias de uso. du tiene que leer cada directorio que recorre, de modo que sobre un árbol grande tarda —la primera vez; la segunda, la caché del tema 37 lo acelera—, y donde no tiene permiso de lectura responde Permission denied y no cuenta lo que hay. Para medir fuera del directorio personal se usa con sudo.

6. Ordenar y profundizar

La utilidad real de du aparece al combinarlo. La pregunta habitual no es cuánto pesa un directorio, sino cuál de sus subdirectorios es el que pesa. Se arma con tres piezas conocidas: du a un nivel de profundidad, el sort -h del tema 26, que ordena cantidades con unidades, y tail.

terminal: los subdirectorios más pesados
$ du -h --max-depth=1 ~ | sort -h | tail -n 7
1,2M	/home/ana/practica
310M	/home/ana/.config
1,4G	/home/ana/snap
3,6G	/home/ana/.cache
12G	/home/ana/Descargas
23G	/home/ana/Vídeos
41G	/home/ana
la tubería, leída
du -h --max-depth=1 ~ | sort -h | tail -n 7
       │                   │         │
       │                   │         └─ quedarse con los siete mayores
       │                   └─ ordenar entendiendo K, M y G
       └─ un total por cada subdirectorio inmediato

La última línea es el total del directorio, y las anteriores, sus partes, de menor a mayor. Aparecen también los directorios ocultos, y es una de las razones para preferir esta forma a du -sh *: el asterisco, como vimos en el tema 9, no incluye los nombres que empiezan con punto, y es justamente en ~/.cache y ~/.local donde suelen esconderse los gigabytes.

El método es repetir el comando, bajando cada vez por la rama más pesada. Para el sistema entero:

terminal: de la raíz hacia abajo
$ sudo du -xh --max-depth=1 / 2> /dev/null | sort -h | tail -n 5
212M	/boot
7,4G	/var
9,8G	/usr
41G	/home
61G	/
$ sudo du -xh --max-depth=1 /var | sort -h | tail -n 4
212M	/var/cache
1,3G	/var/log
5,9G	/var/lib
7,4G	/var

Aquí la opción -x es imprescindible. Sin ella, du entraría en /proc, en /run, en cada snap montado y en cualquier disco externo conectado, y sumaría como espacio del disco cosas que no están en él. Con ella, el total de la última línea —61 G— coincide con el Used de df. Las partes listadas no llegan a sumar ese total porque --max-depth muestra directorios, y en la raíz hay también un archivo: los 2 G de /swap.img.

7. Por qué los tamaños no coinciden

ls -l y du miden cosas distintas, y por eso dan números distintos para el mismo archivo.

El tamaño de un archivo es la cantidad de bytes de su contenido. El espacio ocupado es la cantidad de bloques del disco que tiene asignados. ls -l muestra lo primero; du, lo segundo.

terminal
$ ls -l estado.txt
-rw-rw-r-- 1 ana ana 437 oct 13 09:58 estado.txt
$ du -h estado.txt
4,0K	estado.txt
$ du -h --apparent-size estado.txt
437	estado.txt

El sistema de archivos reparte el espacio en bloques, que en ext4 son de 4096 bytes. Un archivo de 437 bytes ocupa un bloque entero, y uno de 4097, dos. La diferencia es insignificante en un archivo, y considerable en un millón: un directorio con muchísimos archivos pequeños ocupa bastante más que la suma de sus tamaños. Los dos números están, por lo demás, en la salida de stat, en los campos Size y Blocks.

La diferencia también puede ir en el otro sentido. Un archivo puede declarar un tamaño enorme y no ocupar casi nada, si tiene tramos que nunca se escribieron: el sistema de archivos no les asigna bloques. Se llaman archivos dispersos, y se fabrica uno con truncate, que fija el tamaño de un archivo sin escribir en él:

terminal
$ truncate -s 1G hueco.img
$ ls -lh hueco.img
-rw-rw-r-- 1 ana ana 1,0G oct 13 10:31 hueco.img
$ du -h hueco.img
0	hueco.img
$ rm hueco.img

No es una curiosidad: así son las imágenes de disco de las máquinas virtuales, que declaran 40 G y ocupan lo que realmente tengan escrito. Quien las mide con ls se asusta sin motivo.

Se observaExplicación
du da más que ls -l.El espacio se asigna por bloques de 4 K: cada archivo ocupa un número entero de bloques.
du da mucho menos que ls -l.Es un archivo disperso, o el sistema de archivos comprime.
Un directorio vacío «pesa» 4,0K.Es el bloque que ocupa su lista de nombres.
Dos directorios con los mismos archivos suman menos que el doble.Comparten archivos por enlaces duros. du cuenta cada inodo una sola vez, como corresponde según el tema 14.
du no cuenta el destino de un enlace simbólico.Mide el enlace, que son unos bytes. Con -L lo sigue.

Para saber cuánto lugar se va a recuperar borrando algo, el número que vale es el de du. Para saber cuánto se va a transferir al copiarlo a otro equipo, el de du --apparent-size.

8. Encontrar qué llena el disco

El caso práctico del tema: df muestra un sistema de archivos al 95 %, y hay que encontrar adónde fue el espacio. Es un procedimiento, y siempre el mismo.

  1. Identificar cuál se llena: df -h. Anotar el punto de montaje. dónde
  2. Descartar los inodos: df -i, si hay espacio y aun así no se puede escribir. dónde
  3. Medir el primer nivel: sudo du -xh --max-depth=1 /punto | sort -h | tail. quién
  4. Bajar por la rama más pesada, repitiendo el comando, hasta dar con el directorio o el archivo. quién
  5. Decidir qué hacer con lo encontrado, con el método que corresponda a cada cosa. limpiar

Los pasos tres y cuatro tienen una versión interactiva, que hace el recorrido una sola vez y deja navegar el resultado. Es ncdu, el paquete que instalamos en el tema 35:

terminal: la pantalla de ncdu
$ ncdu ~
ncdu 1.19 ~ Use the arrow keys to navigate, press ? for help
--- /home/ana -----------------------------------------------------------------
   23,0 GiB [##########] /Vídeos
   12,0 GiB [#####     ] /Descargas
    3,6 GiB [#         ] /.cache
    1,4 GiB [          ] /snap
  310,2 MiB [          ] /.config
  188,4 MiB [          ] /.local
    1,2 MiB [          ] /practica
…
 Total disk usage:  41,0 GiB  Apparent size:  40,8 GiB  Items: 184213
TeclaAcción
Flechas arriba y abajoMover la selección.
Enter, flecha derechaEntrar en el directorio seleccionado.
Flecha izquierdaVolver al directorio padre.
n, sOrdenar por nombre; por tamaño.
gAlternar entre barras y porcentajes.
dBorrar lo seleccionado, con confirmación.
?, qAyuda; salir.

Para el disco del sistema se lo invoca como sudo ncdu -x /, con la misma -x que du y por la misma razón. La tecla d borra de verdad, sin papelera, y con sudo puede borrar cualquier cosa: conviene usar ncdu para encontrar, y borrar después con el comando adecuado.

Un tercer camino, cuando se sospecha de archivos sueltos y no de directorios, es el find del tema 10: sudo find / -xdev -type f -size +500M lista todos los archivos de más de 500 MiB del sistema de archivos raíz.

Los lugares donde el espacio suele irse, y la manera correcta de recuperarlo en cada uno:

LugarContieneCómo se limpia
/var/cache/apt/archivesPaquetes .deb ya instalados.sudo apt clean
/usr/lib/modules, /bootKernels viejos.sudo apt autoremove
/var/logLos registros del sistema.Con las herramientas del tema 39. No se borran a mano los que están en uso.
/var/lib/snapdLos snaps, con sus revisiones anteriores.Quitar los que no se usen, con snap remove.
/var/lib/flatpakAplicaciones y runtimes.flatpak uninstall --unused
/var/lib/dockerImágenes y contenedores.Con los comandos del propio Docker.
~/.cacheCachés de los programas: miniaturas, páginas del navegador.Se puede borrar su contenido, con los programas cerrados. Se regenera.
~/.local/share/TrashLa papelera del escritorio. Lo borrado desde el administrador de archivos sigue ocupando lugar.Vaciar la papelera.
~/DescargasInstaladores, imágenes .iso, archivos repetidos.Revisar a mano.

La regla general: lo que pertenece a un programa se limpia con ese programa. Borrar con rm dentro de /var/lib o /usr deja inconsistente la base de datos de quien administra esos archivos, por lo que vimos en el tema 35.

9. Cuando df y du no están de acuerdo

A veces el procedimiento anterior no cierra: df dice que hay 200 G usados, y du, sumando todo, encuentra 120. Faltan 80 que no están en ningún directorio. Tiene tres explicaciones posibles, y la primera es la más frecuente.

Archivos borrados que siguen abiertos

En el tema 14 vimos qué hace rm en realidad: quita un nombre, y el espacio se libera cuando no queda ningún nombre y ningún programa tiene el archivo abierto. Si un servicio escribe en un registro y alguien lo borra para hacer lugar, el archivo desaparece de los directorios —du ya no lo ve— pero sigue existiendo y creciendo, y df lo cuenta. Se los encuentra con lsof, que lista los archivos abiertos por los procesos:

terminal
$ sudo lsof +L1
COMMAND   PID   USER   FD   TYPE DEVICE    SIZE/OFF NLINK    NODE NAME
rsyslogd  812 syslog   7w   REG    8,2 85899345920     0 1311045 /var/log/syslog.1 (deleted)

La opción +L1 pide los archivos abiertos con menos de un enlace, es decir, sin ningún nombre. Aquí hay uno de 80 G, marcado (deleted), en manos del proceso 812. El espacio vuelve en el momento en que ese proceso lo cierra, lo que se consigue reiniciando el servicio, como veremos en el tema 39. La lección es de método: un registro que crece no se borra. Se lo vacía, con > archivo, la redirección sin comando del tema 23, que deja el mismo archivo con cero bytes.

Archivos tapados por un montaje

Si se monta un disco sobre un directorio que no estaba vacío, lo que había queda oculto —no borrado— mientras dure el montaje, como veremos en la sección 11. Sigue ocupando lugar en el disco de abajo, y ningún du puede llegar a verlo.

La reserva y lo que du no pudo leer

La reserva del 5 % de la sección 4 explica diferencias en el espacio disponible, no en el usado. Y un du ejecutado sin sudo saltea todo lo que no puede leer: si hubo mensajes de Permission denied, el total es incompleto.

10. Montar: el árbol único

Queda la segunda deuda. En el tema 6 dijimos que Linux no tiene letras de unidad: hay un solo árbol, y un segundo disco aparece como un directorio más.

Montar un sistema de archivos es asociarlo a un directorio del árbol, el punto de montaje. A partir de ese momento, lo que se ve al entrar en ese directorio es el contenido del sistema de archivos montado. Desmontar es deshacer la asociación.

A la izquierda, el árbol del sistema con la raíz y los directorios home, usr y mnt. A la derecha, una memoria USB con una carpeta fotos y un archivo informe.pdf. Al montarla en mnt, su contenido aparece como /mnt/fotos y /mnt/informe.pdf / home usr mnt /mnt/fotos /mnt/informe.pdf el árbol del sistema, en /dev/sda2 memoria USB /dev/sdb1 fotos/ informe.pdf mount
La memoria no agrega una raíz nueva: su contenido se cuelga de un directorio que ya existía. Para los programas, /mnt/fotos es una ruta como cualquier otra.

Todo el árbol se arma así. Al arrancar, el kernel monta un sistema de archivos en /, y sobre él se van montando los demás: la partición de arranque en /boot/efi, los de memoria en /run y /dev/shm, el de /proc, cada snap en su directorio. La consecuencia práctica es la que venimos aprovechando desde el tema 6: ningún comando necesita saber en qué disco está un archivo. cp, grep y find trabajan con rutas, y cruzan de un disco a otro sin enterarse.

Para ver qué hay montado, y dónde, el comando es findmnt:

terminal
$ findmnt -t ext4,vfat
TARGET      SOURCE    FSTYPE OPTIONS
/           /dev/sda2 ext4   rw,relatime
└─/boot/efi /dev/sda1 vfat   rw,relatime,fmask=0077,dmask=0077,codepage=437,…
$ findmnt -T ~/practica                 # ¿a qué montaje pertenece esta ruta?
TARGET SOURCE    FSTYPE OPTIONS
/      /dev/sda2 ext4   rw,relatime
ColumnaContiene
TARGETEl punto de montaje.
SOURCEEl dispositivo.
FSTYPEEl tipo de sistema de archivos.
OPTIONSLas opciones con que se montó: rw, lectura y escritura; ro, solo lectura.

Sin opciones, findmnt muestra el árbol completo de montajes, que en un sistema actual tiene varias decenas de líneas; el filtro -t lo reduce a los tipos que interesan. La misma información, sin formato, la da mount ejecutado sin argumentos, y viene de /proc/mounts.

En un escritorio, montar ocurre solo. Al conectar una memoria USB, el sistema la detecta, la monta en /media/usuario/ETIQUETA y la muestra en el administrador de archivos:

terminal: después de conectar una memoria
$ lsblk -e 7
NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINTS
sda      8:0    0 238,5G  0 disk
├─sda1   8:1    0     1G  0 part /boot/efi
└─sda2   8:2    0 237,4G  0 part /
sdb      8:16   1  14,9G  0 disk
└─sdb1   8:17   1  14,9G  0 part /media/ana/DATOS
$ ls /media/ana/DATOS
fotos  informe.pdf
$ df -h /media/ana/DATOS
Filesystem      Size  Used Avail Use% Mounted on
/dev/sdb1        15G  3,2G   12G  22% /media/ana/DATOS

Las dos líneas nuevas son el disco sdb, con un 1 en la columna RM porque es extraíble, y su única partición, ya montada. DATOS es la etiqueta de la memoria; si no tuviera, el directorio llevaría su UUID. Comparar la salida de lsblk antes y después de conectar es la manera segura de saber qué nombre recibió el dispositivo.

11. mount: montar a mano

En un servidor no hay escritorio que monte nada, y aun en un escritorio a veces hace falta elegir dónde o con qué opciones. El comando es mount, con dos argumentos: qué se monta y dónde.

la forma general
sudo mount /dev/sdb1 /mnt
             │        │
             │        └─ el punto de montaje: un directorio que ya existe
             └─ el dispositivo: la partición, no el disco

Para probarlo con la memoria, primero se deshace el montaje automático, con el comando que usa el propio escritorio y que no pide privilegios:

terminal
$ udisksctl unmount -b /dev/sdb1
Unmounted /dev/sdb1.
$ ls /mnt                              # vacío: es un directorio común
$ sudo mount /dev/sdb1 /mnt
$ ls -l /mnt
total 2180
drwxr-xr-x 2 root root   16384 sep 20 11:05 fotos
-rwxr-xr-x 1 root root 2213894 oct  2 17:44 informe.pdf
$ touch /mnt/prueba.txt
touch: cannot touch '/mnt/prueba.txt': Permission denied

El montaje funcionó: mount detectó por su cuenta el tipo de sistema de archivos, y el contenido de la memoria está en /mnt, el directorio que el tema 8 reservó para esto. Pero todo figura como propiedad de root, y no se puede escribir. La causa está en la tabla de la sección 1: vfat no guarda dueños ni permisos. Linux tiene que inventarlos, y sin otra indicación le asigna todo a quien montó. Se corrige con una opción de montaje, usando el id del tema 16 para no tener que recordar el propio número de usuario:

terminal
$ sudo umount /mnt
$ sudo mount -o uid=$(id -u),gid=$(id -g) /dev/sdb1 /mnt
$ ls -l /mnt | tail -n 1
-rwxr-xr-x 1 ana ana 2213894 oct  2 17:44 informe.pdf
$ touch /mnt/prueba.txt               # ahora sí

Esto explica también por qué en una memoria USB chmod y chown no tienen efecto, y por qué todos los archivos aparecen como ejecutables: no hay dónde guardar esos datos. Un disco externo formateado con ext4 se comporta como el resto del sistema, con sus dueños y permisos de verdad.

Se escribeEfecto
sudo mount dispositivo directorioMonta, detectando el tipo.
-o roMonta en solo lectura. Para examinar un disco sin riesgo de modificarlo.
-o uid=N,gid=NEn sistemas de archivos sin dueños, asigna todo a ese usuario y grupo.
-t tipoIndica el tipo, cuando no se puede detectar.
-o loopMonta un archivo como si fuera un dispositivo.
sudo mount -o remount,ro directorioCambia las opciones de algo ya montado, sin desmontarlo.
udisksctl mount -b dispositivoMonta como lo hace el escritorio: en /media, a nombre del usuario y sin sudo.

La opción loop cierra el círculo abierto con los snaps. Un archivo que contiene un sistema de archivos —típicamente la imagen .iso de un disco de instalación— se puede montar y recorrer sin grabarlo en ningún lado:

terminal
$ sudo mount -o loop ~/Descargas/ubuntu-24.04.3-desktop-amd64.iso /mnt
mount: /mnt: WARNING: source write-protected, mounted read-only.
$ ls /mnt
boot  boot.catalog  casper  dists  EFI  install  md5sum.txt  pool
$ sudo umount /mnt

La advertencia es informativa: una imagen ISO es de solo lectura por naturaleza. Mientras está montada, aparece en lsblk como un loop más.

Montar sobre un directorio con contenido lo oculta

El punto de montaje puede ser cualquier directorio. Si no está vacío, mount no avisa: lo que había queda tapado por el contenido de lo montado, invisible e inaccesible, hasta que se desmonta. No se pierde nada, pero el susto es considerable, y el espacio que ocupa pasa a ser uno de los casos de la sección 9. Se monta siempre sobre un directorio vacío: /mnt, o uno creado para eso con mkdir.

Quien no tenga una memoria a mano puede practicar igual. Un sistema de archivos en memoria no necesita ningún dispositivo:

terminal: practicar sin hardware
$ sudo mount -t tmpfs -o size=64M tmpfs /mnt
$ df -h /mnt
Filesystem      Size  Used Avail Use% Mounted on
tmpfs            64M     0   64M   0% /mnt
$ sudo cp /etc/hostname /mnt/ && ls /mnt
hostname
$ sudo umount /mnt && ls /mnt          # desmontado: /mnt vuelve a estar vacío

12. umount: desmontar

El comando se llama umount, sin la primera n de unmount: es una abreviatura de los años setenta, y el error de tipeo más repetido del tema. Recibe el punto de montaje o el dispositivo, indistintamente.

terminal
$ cd /mnt/fotos
$ sudo umount /mnt
umount: /mnt: target is busy.
$ cd ~
$ sudo umount /mnt
$ ls /mnt                              # vacío otra vez

Un sistema de archivos no se puede desmontar mientras alguien lo usa, y «usarlo» incluye lo más inocente: tener una shell parada dentro, que fue lo que ocurrió aquí. Es el error que todos cometen, y casi siempre el culpable es uno mismo, en esa terminal o en otra.

Quién lo tiene ocupadoCómo se lo encuentraSolución
La propia shell, parada en un directorio de adentro.pwdcd a otro lugar.
Otra terminal, o el administrador de archivos, abiertos allí.Mirar las ventanas.Cerrarlos, o llevarlos a otro directorio.
Un programa con un archivo abierto: un visor, un editor, una copia en marcha.sudo lsof +f -- /mnt, que lista los archivos abiertos en ese montaje y qué proceso tiene cada uno.Cerrar el programa, o esperar que termine.
Antes de desconectar, se desmonta

Como vimos en el tema 37, el kernel usa la memoria como caché de disco, y eso vale también para las escrituras: cuando cp termina y devuelve el indicador, parte de los datos puede estar todavía en la memoria, esperando su turno de ir al dispositivo. Retirar una memoria USB en ese momento deja archivos truncados, o el sistema de archivos dañado. umount no vuelve hasta que todo está escrito: es la orden que garantiza que los datos llegaron. Si tarda, es porque está escribiendo; hay que esperarlo. El comando sync fuerza esa escritura sin desmontar, y udisksctl power-off -b /dev/sdb desmonta y además apaga el dispositivo, que es lo que hace el botón «expulsar» del escritorio.

Hay una opción para forzar la salida, umount -l, que desprende el montaje del árbol de inmediato y lo desmonta de verdad cuando deja de estar en uso. Sirve para destrabar una carpeta de red que no responde. No sirve como atajo antes de desconectar un dispositivo, porque no garantiza que la escritura haya terminado.

13. /etc/fstab: los montajes permanentes

Lo montado con mount dura hasta que se lo desmonta, o hasta el próximo reinicio. Los sistemas de archivos que deben estar siempre —empezando por la raíz— se declaran en un archivo de texto, que el sistema lee al arrancar.

terminal
$ cat /etc/fstab
# <file system> <mount point>   <type>  <options>       <dump>  <pass>
# / was on /dev/sda2 during curtin installation
/dev/disk/by-uuid/3b8f2c6e-71d4-4a0b-9c55-0e2f7a91d6b3 / ext4 defaults 0 1
# /boot/efi was on /dev/sda1 during curtin installation
/dev/disk/by-uuid/6C1A-9F3E /boot/efi vfat defaults 0 1
/swap.img	none	swap	sw	0	0

Cada línea es un montaje, con seis campos separados por espacios o tabulaciones:

CampoContieneEn la línea de la raíz
1. QuéEl sistema de archivos: por UUID, por etiqueta o por nombre de dispositivo./dev/disk/by-uuid/3b8f…
2. DóndeEl punto de montaje./
3. TipoEl tipo de sistema de archivos.ext4
4. OpcionesLas mismas de mount -o. defaults son las habituales.defaults
5. dumpUn resto histórico. Siempre 0.0
6. passEl orden en que se verifica al arrancar: 1 para la raíz, 2 para los demás, 0 para no verificar.1

La tercera línea es el área de intercambio del tema 37, que se declara aquí aunque no se monte en ningún directorio. Y el primer campo explica para qué sirve el UUID: como la letra de sdb puede cambiar de un arranque a otro, identificar un disco por su nombre es frágil. El UUID viaja con el sistema de archivos, y lo señala sin ambigüedad esté donde esté conectado. Se lo consulta con lsblk -f, o con sudo blkid:

terminal
$ sudo blkid /dev/sdb1
/dev/sdb1: LABEL="DATOS" UUID="4C2B-91A7" BLOCK_SIZE="512" TYPE="vfat"
$ ls -l /dev/disk/by-uuid/ | awk '{print $9, $10, $11}'

3b8f2c6e-71d4-4a0b-9c55-0e2f7a91d6b3 -> ../../sda2
4C2B-91A7 -> ../../sdb1
6C1A-9F3E -> ../../sda1

El directorio /dev/disk/by-uuid está hecho de enlaces simbólicos, uno por cada sistema de archivos, que el sistema mantiene al día: una aplicación directa del tema 14.

Para que un disco de datos se monte en cada arranque se agrega una línea. Por ejemplo, para un disco externo que debe aparecer en /datos:

una línea para agregar a /etc/fstab
UUID=9d1c5e20-4f6a-4b7e-a2c3-58e0b1f7d944  /datos  ext4  defaults,nofail  0  2
Un error en fstab puede impedir el arranque

El sistema monta al arrancar todo lo que fstab declara, y si una línea está mal escrita, o nombra un disco que no está conectado, puede detenerse en una consola de emergencia en lugar de iniciar. Tres precauciones lo evitan. Hacer una copia antes de editar: sudo cp /etc/fstab /etc/fstab.bak. Agregar la opción nofail a todo disco que pueda faltar, para que su ausencia no detenga el arranque. Y probar antes de reiniciar, con sudo mount -a, que monta todo lo declarado que aún no esté montado: si ese comando da un error, el arranque lo daría también, y se está a tiempo de corregir.

Una ventaja adicional: lo que está en fstab se puede montar nombrando solo el punto de montaje, sudo mount /datos, porque el resto de los datos ya está escrito.

14. Recetas y errores comunes

Quiero…Comando
Ver los discos y particiones, sin los snapslsblk -e 7
Ver el tipo y el UUID de cada sistema de archivoslsblk -f
Saber qué nombre recibió la memoria que conectélsblk, antes y después
Ver el espacio libre, sin ruidodf -h -x tmpfs -x squashfs
Ver el espacio libre donde estoydf -h .
Saber en qué disco está un directoriodf -h ruta, o findmnt -T ruta
Ver los inodos libresdf -i
Saber cuánto ocupa un directoriodu -sh directorio
Ver los subdirectorios más pesadosdu -h --max-depth=1 . | sort -h | tail
Hacer lo mismo en todo el disco del sistemasudo du -xh --max-depth=1 / | sort -h | tail
Recorrer el uso del disco de forma interactivasudo ncdu -x /
Listar los archivos de más de 500 MiBsudo find / -xdev -type f -size +500M
Encontrar el directorio con más archivossudo du --inodes -x --max-depth=2 /var | sort -n | tail
Encontrar archivos borrados que siguen ocupando lugarsudo lsof +L1
Vaciar un archivo sin borrarlo> archivo
Ver qué hay montadofindmnt -t ext4,vfat,exfat,ntfs
Montar una memoria USB a mano, con mis permisossudo mount -o uid=$(id -u),gid=$(id -g) /dev/sdb1 /mnt
Montarla como lo hace el escritorioudisksctl mount -b /dev/sdb1
Examinar una imagen ISOsudo mount -o loop imagen.iso /mnt
Desmontarsudo umount /mnt
Saber qué impide desmontarsudo lsof +f -- /mnt
Probar /etc/fstab sin reiniciarsudo mount -a
SíntomaCausaSolución
No space left on deviceEl sistema de archivos está lleno.df -h, y el procedimiento de la sección 8.
No space left on device, y df -h muestra espacio.Se agotaron los inodos.df -i; buscar el directorio con millones de archivos.
El completado con Tab falla con un mensaje sobre un archivo temporal.La shell no puede crear archivos: el disco está lleno.Liberar espacio.
df muestra muchas líneas loop al 100 %.Son los snaps, de solo lectura.Ignorarlas, o -x squashfs.
El disco «de 256 GB» muestra 238 G.El fabricante cuenta en potencias de 1000, y lsblk, en potencias de 1024.Es el mismo tamaño. df -H muestra las del fabricante.
Used más Avail no suman Size.La reserva del 5 % para root.Es lo normal.
du -sh * da mucho menos que du -sh .El asterisco no incluye los directorios ocultos.du -h --max-depth=1 .
du muestra Permission denied.Hay directorios que no puedes leer, y no se contaron.Repetir con sudo.
du de / da más que el tamaño del disco.Entró en otros sistemas de archivos montados.Agregar -x.
ls -l y du dan tamaños distintos.Uno muestra el tamaño y el otro, el espacio ocupado.Los dos son correctos. Sección 7.
Borré archivos grandes y el espacio no volvió.Un proceso los tiene abiertos; o fueron a la papelera.sudo lsof +L1; vaciar la papelera.
unmount: command not foundEl comando es umount.sudo umount /mnt
umount: target is busyAlgo usa el sistema de archivos; lo más probable, tu propia shell.cd ~; lsof +f -- punto.
mount: only root can do thatMontar es una operación de administrador.sudo, o udisksctl mount.
mount: wrong fs type, bad option, bad superblockSe nombró el disco en lugar de la partición, o falta soporte para ese tipo, o el sistema de archivos está dañado.Verificar con lsblk -f: sdb1, no sdb.
mount: mount point does not existEl directorio de destino no existe.Crearlo con mkdir.
Monté un disco y los archivos del directorio desaparecieron.Quedaron tapados por el montaje.Desmontar; montar en un directorio vacío.
En la memoria USB no puedo escribir, y todo es de root.vfat no guarda dueños: se asignan al montar.Montar con -o uid=…,gid=….
chmod no cambia nada en la memoria USB.El sistema de archivos no guarda permisos.Es lo esperado.
El sistema de archivos pasó solo a Read-only file system.El kernel detectó errores y lo protegió.Guardar lo importante: puede ser un disco que falla.

La referencia del tema:

Se escribeQué hace
lsblk, lsblk -e 7, lsblk -fLista los dispositivos; sin los loop; con sus sistemas de archivos.
df -hEspacio total, usado y disponible de cada sistema de archivos.
df -h rutaEl del sistema de archivos que contiene esa ruta.
df -hT, df -iCon el tipo; los inodos.
du -sh directorioCuánto ocupa un directorio con todo su contenido.
du -h --max-depth=1 dir | sort -hSus subdirectorios, ordenados por tamaño.
du -xSin salir del sistema de archivos de partida.
ncdu -x directorioExplora el uso del disco de forma interactiva.
findmnt, findmnt -T rutaLo montado; el montaje al que pertenece una ruta.
sudo mount dispositivo directorioMonta un sistema de archivos.
sudo mount -o ro, -o loopEn solo lectura; un archivo de imagen.
sudo umount directorioDesmonta, después de escribir todo lo pendiente.
udisksctl mount -b, unmount -b, power-off -bMonta, desmonta y apaga un dispositivo extraíble, sin sudo.
sudo blkidMuestra etiqueta, UUID y tipo de cada sistema de archivos.
/etc/fstab, sudo mount -aLos montajes permanentes; montar todo lo declarado.

Con este tema el sistema queda inventariado: procesador, memoria y discos. Pero un sistema no es solo sus recursos. Buena parte de lo que hace lo hacen programas que nadie lanzó desde una terminal y que trabajan en silencio: el que atiende la red, el que registra los eventos, el que ejecuta las actualizaciones automáticas. Varias veces en este bloque dijimos «se reinicia el servicio» o «queda anotado en el registro». En el tema 39 aprendemos a hacer las dos cosas, con systemctl y journalctl.

15. Resumen

16. Preguntas de repaso

Intenta responder cada una antes de abrir la respuesta.

1. ¿Qué diferencia hay entre una partición y un sistema de archivos?

La partición es una porción del disco, espacio en bruto. El sistema de archivos es la organización que se graba en ella —inodos, bloques, directorios— para poder guardar archivos.

2. En la salida de lsblk aparecen loop0, loop1, loop2… ¿Qué son, y cómo se los quita de la lista?

Son archivos montados como si fueran discos; en Ubuntu, los paquetes snap. Se excluyen con lsblk -e 7.

3. Conectas una memoria USB. ¿Cómo averiguas con seguridad qué nombre de dispositivo recibió?

Ejecutando lsblk antes y después de conectarla: las líneas nuevas, con un 1 en la columna RM, son la memoria y sus particiones.

4. ¿Qué responde df -h ~/Descargas?

El espacio total, usado y disponible del sistema de archivos que contiene ese directorio, con su dispositivo y su punto de montaje.

5. En df -h hay líneas de tipo tmpfs. ¿Ocupan lugar en el disco?

No. Son sistemas de archivos que residen en la memoria; lo que contienen se pierde al apagar.

6. Un sistema de archivos ext4 muestra 100 G de capacidad, 60 usados y 35 disponibles. ¿Dónde están los 5 que faltan?

En la reserva del 5 % para root, que los usuarios comunes no pueden ocupar, y que permite al sistema seguir funcionando con el disco lleno.

7. Un programa falla con No space left on device, y df -h muestra 40 G libres. ¿Qué verificas?

df -i: probablemente se agotaron los inodos, porque hay una cantidad enorme de archivos pequeños.

8. ls -ld proyecto muestra 4096 y du -sh proyecto muestra 2,3G. ¿Por qué?

ls muestra lo que ocupa el directorio en sí, su lista de nombres. du suma lo que ocupa todo su contenido.

9. ¿Qué hace du -h --max-depth=1 /var | sort -h | tail -n 5?

Calcula cuánto ocupa cada subdirectorio inmediato de /var, los ordena por tamaño entendiendo las unidades, y muestra los cinco mayores; el último es el total de /var.

10. ¿Para qué sirve la opción -x de du, y por qué es necesaria al medir /?

Impide que du entre en otros sistemas de archivos montados. Sin ella sumaría /proc, los snaps y los discos externos como si estuvieran en el disco del sistema.

11. Un archivo de 100 bytes ocupa 4,0K según du. ¿Por qué?

Porque el sistema de archivos asigna el espacio en bloques de 4096 bytes, y todo archivo ocupa un número entero de bloques.

12. Borraste un registro de 50 G y df muestra el mismo espacio usado. ¿Qué pasó, y cómo lo confirmas?

El proceso que lo escribe lo tiene abierto, y el espacio no se libera hasta que lo cierre. Se confirma con sudo lsof +L1, y se resuelve reiniciando ese servicio.

13. ¿Qué significa «montar» un sistema de archivos?

Asociarlo a un directorio del árbol, el punto de montaje, de modo que su contenido se vea al entrar en ese directorio.

14. Montas una memoria con sudo mount /dev/sdb1 /mnt y no puedes escribir en ella. ¿Por qué, y cómo se resuelve?

Porque vfat no guarda dueños, y todo se asignó a root, que fue quien montó. Se monta con -o uid=$(id -u),gid=$(id -g).

15. umount responde target is busy. ¿Cuál es la causa más probable?

Que una shell —a menudo la propia— esté parada en un directorio de ese sistema de archivos, o que un programa tenga abierto un archivo de él.

16. ¿Por qué hay que desmontar una memoria USB antes de retirarla?

Porque las escrituras pasan por la caché en memoria, y pueden no haber llegado todavía al dispositivo. umount espera a que todo esté escrito.

17. ¿Por qué /etc/fstab identifica los discos por UUID y no por nombre de dispositivo?

Porque nombres como sdb dependen del orden en que se detectan los discos y pueden cambiar. El UUID pertenece al sistema de archivos y no cambia.

Para practicar

  1. Ejecuta lsblk, lsblk -e 7 y lsblk -f. ¿Cuántos discos reales tienes, cuántas particiones, y qué sistema de archivos tiene cada una?
  2. Muestra el espacio de los sistemas de archivos reales, excluyendo los de memoria y los snaps. Crea un alias para ese comando y agrégalo a tu .bashrc.
  3. Averigua con df -h en qué sistema de archivos están ~, /tmp, /dev/shm, /boot y /run. ¿Cuáles están en el disco y cuáles en la memoria?
  4. Compara df -h / con df -H /, y con df -i /. Calcula qué porcentaje de los inodos está en uso.
  5. Mide ~/practica con du -sh. Luego lista sus elementos con du -ah, ordenados por tamaño. ¿Cuál es el archivo más grande?
  6. Encuentra los cinco subdirectorios más pesados de tu directorio personal. Compara el resultado con el de du -sh ~/*: ¿qué directorios no aparecen en el segundo?
  7. Crea un archivo con una sola letra y compara ls -l, du -h y du -h --apparent-size. Repite con un archivo disperso de 500 MiB creado con truncate, y bórralo.
  8. Con sudo du -xh --max-depth=1, recorre el disco del sistema desde /, bajando tres niveles por la rama más pesada. Haz el mismo recorrido con sudo ncdu -x /, sin borrar nada.
  9. Ejecuta findmnt -t ext4,vfat y cat /etc/fstab. Relaciona cada línea del archivo con un montaje, y cada UUID con la salida de lsblk -f.
  10. Monta en /mnt un tmpfs de 32 MiB. Compruébalo con df -h /mnt y findmnt /mnt, copia dentro un archivo, intenta desmontarlo desde adentro, sal y desmóntalo. Si tienes una memoria USB, repite montándola a mano con tus permisos, y expúlsala con udisksctl.