linux - numero - inodes used
¿Dónde se están utilizando todos mis inodes? (14)
¿Cómo averiguo qué directorios son responsables de masticar todos mis inodes?
En última instancia, el directorio raíz será responsable de la mayor cantidad de inodos, por lo que no estoy seguro de qué tipo de respuesta quiero.
Básicamente, me estoy quedando sin inodos disponibles y necesito encontrar un directorio innecesario para descartar.
Gracias, y perdón por la vaga pregunta.
Solo quería mencionar que también puede buscar indirectamente usando el tamaño del directorio, por ejemplo:
find /path -type d -size +500k
Donde 500k podría aumentar si tiene muchos directorios grandes.
Tenga en cuenta que este método no es recursivo. Esto solo lo ayudará si tiene muchos archivos en un solo directorio, pero no si los archivos están distribuidos uniformemente entre sus descendientes.
Este comando funciona en casos muy poco probables donde la estructura de su directorio es idéntica a la mía:
find / -type f | grep -oP ''^/([^/]+/){3}'' | sort | uniq -c | sort -n
Aquí hay un script simple de Perl que lo hará:
#!/usr/bin/perl -w
use strict;
sub count_inodes($);
sub count_inodes($)
{
my $dir = shift;
if (opendir(my $dh, $dir)) {
my $count = 0;
while (defined(my $file = readdir($dh))) {
next if ($file eq ''.'' || $file eq ''..'');
$count++;
my $path = $dir . ''/'' . $file;
count_inodes($path) if (-d $path);
}
closedir($dh);
printf "%7d/t%s/n", $count, $dir;
} else {
warn "couldn''t open $dir - $!/n";
}
}
push(@ARGV, ''.'') unless (@ARGV);
while (@ARGV) {
count_inodes(shift);
}
Si quiere que funcione como du
(donde cada recuento de directorios también incluye el conteo recursivo del subdirectorio), cambie la función recursiva para return $count
y luego en el punto de recursión diga:
$count += count_inodes($path) if (-d $path);
Entonces, básicamente, ¿estás buscando qué directorios tienen muchos archivos? Aquí hay una primera puñalada:
find . -type d -print0 | xargs -0 -n1 count_files | sort -n
donde "count_files" es un script de shell que sí lo hace (gracias a Jonathan)
echo $(ls -a "$1" | wc -l) $1
Los métodos provistos con l recursivo son muy lentos. Solo por encontrar rápidamente el directorio padre consumiendo la mayor cantidad de inodos que utilicé:
cd /partition_that_is_out_of_inodes
for i in *; do echo -e "$(find $i | wc -l)/t$i"; done | sort -n
for i in dir.[01] do find $i -printf "%i/n"|sort -u|wc -l|xargs echo $i -- done
dir.0 - 27913
dir.1 - 27913
El script de perl es bueno, pero ten cuidado con los enlaces simbólicos: recurre solo cuando -l filetest devuelve falso o, en el mejor de los casos, contarás demasiado; en el peor, recurrirá indefinidamente (lo que podría ser una preocupación menor) invocar el reinado de 1000 años de Satanás.
La idea de contar inodos en un árbol de sistema de archivos se desmorona cuando hay múltiples enlaces a más de un pequeño porcentaje de los archivos.
Esta es mi opinión sobre ella. No es tan diferente de los demás, pero la salida es bonita y creo que cuenta con inodos más válidos que otros (directorios y enlaces simbólicos). Esto cuenta la cantidad de archivos en cada subdirectorio del directorio de trabajo; clasifica y formatea la salida en dos columnas; e imprime un total general (que se muestra como ".", el directorio de trabajo). Esto no seguirá a los enlaces simbólicos, sino que contará los archivos y directorios que comiencen con un punto. Esto no cuenta los nodos del dispositivo ni los archivos especiales, como los conductos con nombre. Simplemente elimine la prueba "-type l -o-type d -o -type f" si quiere contarlos también. Debido a que este comando se divide en dos comandos de búsqueda, no puede discriminar correctamente contra directorios montados en otros sistemas de archivos (la opción -mount no funcionará). Por ejemplo, esto realmente debería ignorar los directorios "/ proc" y "/ sys". Puede ver que en el caso de ejecutar este comando en "/", incluir "/ proc" y "/ sys" sesga groseramente el total general.
for ii in $(find . -maxdepth 1 -type d); do
echo -e "${ii}/t$(find "${ii}" -type l -o -type d -o -type f | wc -l)"
done | sort -n -k 2 | column -t
Ejemplo:
# cd /
# for ii in $(find -maxdepth 1 -type d); do echo -e "${ii}/t$(find "${ii}" -type l -o -type d -o -type f | wc -l)"; done | sort -n -k 2 | column -t
./boot 1
./lost+found 1
./media 1
./mnt 1
./opt 1
./srv 1
./lib64 2
./tmp 5
./bin 107
./sbin 109
./home 146
./root 169
./dev 188
./run 226
./etc 1545
./var 3611
./sys 12421
./lib 17219
./proc 20824
./usr 56628
. 113207
Solo una nota, cuando finalmente encuentre algún directorio de spool de correo y desee eliminar todo el correo no deseado que está allí, rm * no funcionará si hay demasiados archivos, puede ejecutar el siguiente comando para eliminar rápidamente todo en ese directorio:
* ADVERTENCIA * ESTO BORRARÁ TODOS LOS ARCHIVOS RÁPIDAMENTE PARA CASOS CUANDO rm NO FUNCIONA
find . -type f -delete
Usé lo siguiente para hacer ejercicio (con un poco de ayuda de mi colega James) que teníamos una gran cantidad de archivos de sesión PHP que debían eliminarse en una máquina:
1. ¿Cuántos inodos tengo en uso?
root@polo:/# df -i
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/xvda1 524288 427294 96994 81% /
none 256054 2 256052 1% /sys/fs/cgroup
udev 254757 404 254353 1% /dev
tmpfs 256054 332 255722 1% /run
none 256054 3 256051 1% /run/lock
none 256054 1 256053 1% /run/shm
none 256054 3 256051 1% /run/user
2. ¿Dónde están todos esos inodos?
root@polo:/# find / -xdev -printf ''%h/n'' | sort | uniq -c | sort -k 1 -n
[...]
1088 /usr/src/linux-headers-3.13.0-39/include/linux
1375 /usr/src/linux-headers-3.13.0-29-generic/include/config
1377 /usr/src/linux-headers-3.13.0-39-generic/include/config
2727 /var/lib/dpkg/info
2834 /usr/share/man/man3
416811 /var/lib/php5/session
root@polo:/#
Son muchos archivos de sesión PHP en la última línea.
3. ¿Cómo eliminar todos esos archivos?
Elimine todos los archivos en el directorio que tengan más de 1440 minutos (24 horas):
root@polo:/var/lib/php5/session# find ./ -cmin +1440 | xargs rm
root@polo:/var/lib/php5/session#
4. ¿Ha funcionado?
root@polo:~# find / -xdev -printf ''%h/n'' | sort | uniq -c | sort -k 1 -n
[...]
1088 /usr/src/linux-headers-3.13.0-39/include/linux
1375 /usr/src/linux-headers-3.13.0-29-generic/include/config
1377 /usr/src/linux-headers-3.13.0-39-generic/include/config
2727 /var/lib/dpkg/info
2834 /usr/share/man/man3
2886 /var/lib/php5/session
root@polo:~# df -i
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/xvda1 524288 166420 357868 32% /
none 256054 2 256052 1% /sys/fs/cgroup
udev 254757 404 254353 1% /dev
tmpfs 256054 332 255722 1% /run
none 256054 3 256051 1% /run/lock
none 256054 1 256053 1% /run/shm
none 256054 3 256051 1% /run/user
root@polo:~#
Afortunadamente, teníamos una alerta sensu que nos enviaba un correo electrónico diciendo que nuestros inodos estaban casi agotados.
Esto cuenta los archivos en el directorio actual. Se supone que esto funciona incluso si los nombres de archivo contienen nuevas líneas. Utiliza GNU Awk. Cambie el valor de d para obtener las profundidades de ruta separadas y máximas deseadas. 0 significa profundidad ilimitada.
find . -mount -not -path . -print0 | gawk -v d=2 ''
BEGIN{RS="/0";FS="/";SUBSEP="/";ORS="/0"}
{
s="./"
for(i=2;i!=d+1 && i<NF;i++){s=s $i "/"}
++n[s]
}
END{for(val in n){print n[val] "/t" val "/n"}}'' | sort -gz -k 1,1
Lo mismo por Bash 4; esto es significativamente más lento en mi experiencia:
declare -A n;
d=2
while IFS=/ read -d $''/0'' -r -a a; do
s="./"
for ((i=2; i!=$((d+1)) && i<${#a[*]}; i++)); do
s+="${a[$((i-1))]}/"
done
((++n[/$s]))
done < <(find . -mount -not -path . -print0)
for j in "${!n[@]}"; do
printf ''%i/t%s/n/0'' "${n[$j]}" "$j"
done | sort -gz -k 1,1
Si no desea crear un archivo nuevo (o no puede porque se quedó sin inodos), puede ejecutar esta consulta:
for i in `find . -type d `; do echo `ls -a $i | wc -l` $i; done | sort -n
como se menciona en la información privilegiada en otra respuesta, el uso de una solución con find será mucho más rápido ya que el l recursivo es bastante lento, ¡compruebe a continuación la solución! (crédito donde el crédito se debe!)
Un trazador de líneas realmente funcional (hallazgo de GNU, para otros tipos de hallazgos necesitarías tu propio equivalente de -xdev
para permanecer en el mismo FS).
find / -xdev -type d | while read -ri; do printf "%d %s/n" $(ls -a "$i" | wc -l) "$i"; done | sort -nr | head -10
La cola es, obviamente, personalizable.
Al igual que con muchas otras sugerencias aquí, esto solo le mostrará la cantidad de entradas en cada directorio, de forma no recursiva.
PD
Rápido, pero imprecisa, de una sola línea (detectar por tamaño de nodo de directorio):
find / -xdev -type d -size +100k
utilizar
ncdu -x <path>
luego presione Shitf + c para ordenar por conteo de artículos donde el elemento es archivo