¿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!
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 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.
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>
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.