Inicio » Encontrar directorios demasiado gordos

Encontrar directorios demasiado gordos

Enviado por queru el 1 December 2009 - 9:43pm.

Find Fat Fast

¿Que ocurre cuando se nos llena el disco y no sabemos que es lo que lo ha llenado? Tal vez sean logs descontrolados, o tal vez ficheros de correo, o...

Si preguntamos a algún amigo gafotas, lo más probable es que nos conteste esto:

find / -type d -size +1G

¡Oh! ¡Qué bueno! Diréis, ¡find me permite ver que directorios ocupan más de 1Gb!

PUES NO

No. Eso sólo sirve para ficheros (-type f), ya que el sistema de ficheros, como tamaño del directorio devuelve lo que ocupa en disco dicho directorio, es decir, el tamaño mínimo de bloque, por ejemplo 4Kb, siempre, contenga lo que contenga.

No os preocupéis, yo también fui víctima de la credulidad y de la vagancia, y pasaron unas horas antes de darme cuenta de mi error.

La solución:

La solución más elegante, con la porquería de sistemas de ficheros que gastamos a día de hoy, pasa por hacer un guión que, dado un punto de inicio y un tamaño límite, compute con "du" el tamaño de cada directorio, calculando si excede o no del límite.

He buscado mucho y he encontrado bastantes porquerías, hasta que he decidido hacerlo yo mismo.

buscagordos.sh

Está probado sobre varias versiones de bash, y solamente necesita las utilidades find y du.

Basta con copiarlo a nuestro unix y darle permisos de ejecución:

#!/bin/bash

# Busca directorios demasiado gordos por el disco.
# (GPLv3) jorge@jorgefuertes.com

if [[ $# -lt 2 ]]
then
	echo "BuscaGordos - ©2009 Jorge Fuertes (jorge@jorgefuertes.com)"
	echo "Este software se cede bajo contrato GPLv3."
	echo 
	echo "Busca directorios gordos por el disco."
	echo
	echo "Utilización:"
	echo "  $0  "
	echo "El tamaño límite debe especificarse en (M)egas o (G)igas."
	echo "Ejemplo: $0 /var 100M"
	echo
	exit 1
fi

echo "Buscando directorios más gordos de $2 en $1..."
echo

echo $2 | egrep ".*G$" &> /dev/null
if [[ $? -eq 0 ]]
then
	MLIMIT=$(expr $(echo $2|cut -f1 -d"G") \* 1024)
else
	MLIMIT=$(echo $2|cut -f1 -d"M")
fi
KLIMIT=$(expr $MLIMIT \* 1024)

for i in $(find $1 -maxdepth 1 -type d) 
do
	SIZE=$(du -xs \
		--exclude="/sys" \
       		--exclude="/proc" \
		--exclude="/dev" \
		$i 2> /dev/null | tr -s "\t" "|" | cut -f1 -d"|")
	if [[ $SIZE -gt $KLIMIT ]]
	then
		MEGAS=$(expr $SIZE / 1024)
		if [[ $MEGAS -lt 1024 ]]
		then
			TOTAL="${MEGAS} Mb"
		else
			TOTAL=$(expr $MEGAS / 1024)" Gb"
		fi
		while [[ $(expr length "$TOTAL") -lt 8 ]]
		do
			TOTAL="${TOTAL}."
		done
		
		echo "${TOTAL}: $i"
	fi
done

echo
echo "<EOF>"

Los parámetros son la ruta de inicio y el tamaño máximo para los directorios. Por ejemplo:

$> buscagordos.sh /var 100M
Buscando directorios más gordos de 100M en /var...

38 Gb...: /var
356 Mb..: /var/log
38 Gb...: /var/lib
213 Mb..: /var/cache

<EOF>

¿Falta mucho? Me aburro

En sistemas con muchos ficheros puede tardar bastante, pero podemos dejarlo funcionando en background y que nos escriba el resultado en un fichero:

$> buscagordos.sh /var 100M > gorditos.txt &

¿Dudas? ¿Mejoras? ¿Quejas?

Lo estoy probando, pero le

Lo estoy probando, pero le cuesta un rato largo comprobarlo.
Es en el servidor web, pero aún así se me hace extraño

Tarda un rato.

Tranquilo, es normal, si hay muchos ficheros le cuesta un rato.

Inicio de sesión

Contrato Coloriuris
Copyright © 2010 TrucoLinux.com: Todo el contenido sujeto a contrato ColorIruris salvo que se especifique lo contrario.
Este sitio ha sido totalmente desarrollado y montado sobre software libre: Gentoo GNU/Linux, Apache, MySQL, PHP, Drupal...
Sindicar contenidos: Noticias (RSS).