Los 15 comandos Linux más útiles para mantener sistemas de ficheros

Linux file system commands

Una de las tareas más frecuentes y tediosas del administrador de sistemas es evitar que se llenen los sistemas de ficheros de una máquina, pues cuando un servidor se queda sin espacio las consecuencias son impredecibles. Dependiendo de cómo esté estructurado el sistema de ficheros raíz de dicha máquina y de la división entre distintas particiones o volúmenes que hayamos establecido, dichas consecuencias serán más o menos graves, pero en cualquier caso indeseables.

En cualquier caso siempre es mejor prevenir que curar, por lo que conviene utilizar herramientas que realicen la rotación automática de logs como logrotate y scripts personalizados que vigilen y lleven a cabo acciones periódicas de vaciado para evitar que se nos llenen nuestros sistemas de ficheros. No obstante, aún usando estos métodos de prevención serán muchas las ocasiones en que tendremos que actuar manualmente para solucionar problemas que seguro se producirán.

A continuación recojo una recopilación de los comandos Linux que a mi me resultan más útiles en el día a día para liberar espacio y mantener desde el intérprete de comandos mis sistemas de ficheros en un estado de salud óptimo.

1. Comprobar el espacio libre disponible

Para saber el espacio libre del que disponemos en todos los sistemas de ficheros de nuestra máquina ejecutaremos el siguiente comando:

$ df -h
S.ficheros     Tamaño Usados  Disp Uso% Montado en
/dev/sdb5        3,9G   842M  3,0G  22% /
udev             2,0G   4,0K  2,0G   1% /dev
tmpfs            791M   956K  790M   1% /run
none             5,0M      0  5,0M   0% /run/lock
none             2,0G    72M  1,9G   4% /run/shm
/dev/sdb1        118M    91M   28M  77% /boot
/dev/sdb10        31G   6,8G   24G  23% /home
/dev/sdb6         23G    12G   12G  52% /usr
/dev/sdb7        9,6G   1,5G  8,1G  16% /var
/dev/sdb8        2,9G    62M  2,8G   3% /tmp
/dev/sdb11       102G    11G   91G  11% /vmware
/dev/sda1        230G    93G  125G  43% /var/datos

Para un directorio concreto:

$ df -h /home
S.ficheros     Tamaño Usados  Disp Uso% Montado en
/dev/sdb10        31G   6,8G   24G  23% /home

Para mostrar los sistemas de ficheros por orden de ocupación y saber así cuales son los que están más llenos:

$ df -h | awk '{print $5 " " $6}' | sort -n | tail -5
22% /
23% /home
43% /var/datos
52% /usr
77% /boot

2. Calcular el tamaño ocupado por un directorio

El parámetro -h indica que se muestre el tamaño del modo más amigable posible, ya sea en Kilobytes, Megabytes, Gigabytes o Terabytes.

# du -h -s /var/log
9,6M	/var/log

3. Eliminar vs vaciar ficheros

Para eliminar ficheros con el fin de liberar espacio emplearemos habitualmente el comando rm. Sin embargo, es muy habitual que no nos podamos permitir eliminar un fichero por estar siendo utilizado en ese momento por una aplicación, lo cual es de lo más habitual con ficheros de log en sistemas en producción que no pueden parar. Eliminarlos directamente puede tener consecuencias nefastas, como el bloqueo de la propia aplicación que los está utilizando, o más leves pero también indeseables, como que se interrumpa el volcado de datos a estos ficheros y dejen de ser útiles.

Para no alterar el funcionamiento de una aplicación y conseguir nuestro objetivo de liberar espacio vaciaremos los ficheros en lugar de eliminarlos:

# >/var/log/syslog

Tras esto el fichero quedará con un tamaño de 0 bytes.

Si necesitamos vaciar múltiples ficheros a la vez con un único comando:

# for I in `ls "/var/log/*.log"`;do >"$I";done

4. Contar el número de ficheros en un directorio

# ls -l /var/log | wc -l
80

5. Obtener los ficheros que más pesan de un filesystem

Este comando es útil cuando queremos liberar espacio, pues muestra los ficheros que tienen un mayor tamaño dentro de un directorio incluyendo sus subdirectorios, siendo el último de la lista el más pesado.

# du -k /var/log | sort -n | tail -5
516	/var/log/apache2
5256	/var/log/exim4
12884	/var/log/installer/cdebconf
13504	/var/log/installer
21456	/var/log

El tamaño de los ficheros se debe mostrar Kilobytes (parámetro -k). Es necesario utilizar este parámetro en lugar de -h porque si no el comando sort -n no ordenaría la lista del modo que nosotros esperamos.

Es importante limitar el número de ficheros que queremos mostrar con tail -X, siendo X dicho número, pues si el directorio en cuestión tiene cientos o miles de ficheros, la salida del comando se puede demorar demasiado por la sobrecarga de entrada/salida a la que someteremos a nuestro terminal, sobre todo si nos estamos conectando de forma remota via telnet o ssh a un servidor y la conexión no es muy rápida.

6. Listar los ficheros más pesados de un directorio

Similar al anterior, pero en este caso sólo se muestran los fichero del propio directorio, sin incluir subdirectorios.

# ls -lSr | tail -5
-rw-r----- 1 syslog      adm   118616 sep 29 22:05 auth.log
-rw-r--r-- 1 root        root  149012 sep  9 17:12 udev
-rw-r--r-- 1 root        root  160128 ago  4 19:27 faillog
-rw-r----- 1 syslog      adm   499400 sep 28 06:25 auth.log.1
-rw-rw-r-- 1 root        utmp 1461168 sep 29 21:54 lastlog

Si elimináramos el parámetro -r obtendríamos los ficheros más ligeros en lugar de los de mayor tamaño.

7. Calcular el espacio ocupado por ciertos ficheros

Por ejemplo, si queremos obtener el espacio total ocupado sólo por los ficheros con extensión .log en un directorio, usaremos el siguiente comando:

# du -ch /var/log/*.log | grep total
468K	total

8. Encontrar ficheros de gran tamaño fijando límites

Por ejemplo, aquellos que tengan un tamaño de más de 100 MB, o aquellos que ocupen entre 100 MB y 1 GB:

$ find . -type f -size +100M -ls
$ find . -type f -size +100M -size -1G -ls

9. Listar los ficheros modificados más recientemente

# ls -larth /var/log | tail -5
drwxr-xr-x 20 root              root     4,2K sep 30 12:27 .
-rw-rw-r--  1 root              utmp      11K sep 30 13:03 wtmp
-rw-r-----  1 syslog            adm       13K sep 30 13:03 syslog
-rw-r-----  1 syslog            adm       13K sep 30 13:03 kern.log
-rw-r-----  1 syslog            adm      1000 sep 30 13:03 auth.log

El parámetro -a indica que también se muestren los ficheros ocultos.

10. Encontrar ficheros antiguos (I)

Muchas veces necesitamos saber los ficheros modificados dentro de un intervalo de tiempo dado. En el siguiente ejemplo, localizamos los ficheros que tengan una antigüedad de más de 90 días con el fin de encontrar ficheros antiguos que ya no sirvan y puedan eliminarse para liberar espacio.

# find /var/log -mtime +90 -ls
# find /var/log -mtime +90 -ls -exec rm {} \;

El primer comando sólo localiza los ficheros, el segundo además los elimina.

11. Encontrar ficheros antiguos (II)

Igual que el anterior, pero en este caso también se consideran los ficheros que hayan sido accedidos dentro del intervalo de tiempo especificado, sin que hayan tenido por qué ser modificados.

# find /var/log -atime +90 -ls

12. Encontrar ficheros vacíos

El siguiente comando nos permite encontrar en el directorio actual ficheros con un tamaño de 0 bytes, es decir, vacíos. Esto es útil ante situaciones anómalas en las que se generan este tipo de ficheros, por ejemplo tras llenarse un filesystem o por el comportamiento anómalo de una aplicación. Ante estos escenarios se hace necesaria una limpieza, pues aunque estos ficheros no ocupen espacio en disco sí que pueden llegar a consumir todos los inodos disponibles de un sistema de ficheros si se crean de forma masiva e impedir así que se puedan crear nuevos ficheros.

$ find . -type f -size 0b -ls

O también:

$ find . -type f -empty -ls

Para saber el número de inodos libres del que disponen los distintos sistemas de ficheros de una máquina usaremos el comando df -i.

13. Empaquetar y comprimir el contenido de un directorio

A veces es útil empaquetar todos los ficheros de registro o de log de un directorio en un único fichero comprimido para conservar el estado de dicho directorio en un punto temporal determinado y poder eliminar o vaciar todos esos ficheros con el fin de liberar espacio.

# tar -zcvf var_log.`date +%Y%m%d`.tar.gz /var/log/*.log

El comando anterior comprime todos los ficheros de log en un único fichero comprimido con extensión tar.gz y con la fecha de hoy para que sea más fácil localizar los distintos puntos temporales en el futuro. Veamos cómo conseguir ahorrar espacio, pasando en este ejemplo de 468 MB a 35 MB:

# du -ch /var/log/*.log | grep total
468M	total
# ls -lh var_log.20140930.tar.gz 
-rw-r--r-- 1 root root 35M sep 30 13:36 var_log.20140930.tar.gz

Tras esto podemos proceder a vaciar todos los ficheros de log como en el punto 3.

14. Encontrar ficheros en la papelera de reciclaje

Normalmente cuando enviamos algún fichero a la papelera de reciclaje éste simplemente se mueve a un directorio oculto de nuestra carpeta personal como por ejemplo ~/.local/share/Trash en Ubuntu. Sin embargo, hay aplicaciones específicas que utilizan sus propios directorios para almacenar la basura con un nombre que surge de la combinación de la palabra trash en mayúsculas o minúsculas con alguna secuencia de números, como por ejemplo .Trash001, .trash-002, .Trash_0003, etc.

También cuando montamos sistemas de ficheros externos procedentes de un disco duro externo o una tarjeta SD, el sistema operativo del que procede ha podido guardar ficheros en la papelera, pero el nombre de ésta puede diferir de un sistema operativo a otro y ser distinto del que utiliza nuestra distribución Linux y por tanto no reconocerla. En estos casos nos encontramos con que aunque vaciemos la papelera de reciclaje seguiremos teniendo una gran cantidad de espacio ocupado en nuestro dispositivo sin razón aparente.

Pues bien, la solución pasa por buscar todos los subdirectorios *trash* que haya en nuestro sistema sin diferenciar entre mayúsculas o minúsculas y analizar su contenido para ver si podemos deshacernos de él (no siempre será basura todo lo que encontremos). El comando necesario sería el siguiente y su ejecución puede llevar mucho tiempo, por lo que quizás queramos restringirlo a un sistema de ficheros o directorio concreto:

$ find / -iname "*trash*" -ls

15. Encontrar ficheros repetidos

Por último, ahí va un enorme comando que nos permitirá encontrar y eliminar los ficheros duplicados que haya en un directorio para evitar redundancias innecesarias que pueden ser muy costosas en términos de espacio consumido.

find -not -empty -type f -printf "%s\n" | sort -rn | uniq -d | xargs -I{} -n1 find -type f -size {}c -print0 | xargs -0 md5sum | sort | uniq -w32 --all-repeated=separate | cut -f3-100 -d ' ' | tr '\n.' '\t.' | sed 's/\t\t/\n/g' | cut -f2-100 | tr '\t' '\n' | perl -i -pe 's/([ (){}-])/\\$1/g' | perl -i -pe 's/'\''/\\'\''/g' | xargs -pr rm -v

¿Y a ti? ¿Se te ocurren más comandos útiles que utilices habitualmente para mantener tus filesystems desocupados?

10 comentarios

  1. Andrea Urrego 25/02/2015
    • JOSE VARELA 16/06/2015
  2. tanui 19/05/2015
  3. Eduardo 19/08/2015
  4. Michael A Smith 31/08/2016
  5. Carlos Muñoz 01/01/2017

¡Deja tu comentario!

Tu dirección de correo electrónico no será publicada. Los campos necesarios están marcados *