web-dev-qa-db-fra.com

Où sont tous mes inodes utilisés?

Comment savoir quels répertoires sont chargés de mâcher tous mes inodes?

En fin de compte, le répertoire racine sera responsable du plus grand nombre d'inodes, donc je ne sais pas exactement quel type de réponse je veux.

Fondamentalement, je suis à court d’inodes disponibles et j’ai besoin de trouver un répertoire inutile pour l’abattage.

Merci et désolé pour la question vague.

50
Joel

Donc, fondamentalement, vous cherchez quels répertoires contiennent beaucoup de fichiers? Voici un premier essai:

find . -type d -print0 | xargs -0 -n1 count_files | sort -n

où "count_files" est un script Shell qui le fait (merci Jonathan)

echo $(ls -a "$1" | wc -l) $1
20
Paul Tomblin

Si vous ne souhaitez pas créer de nouveau fichier (ou ne le pouvez pas car vous n'avez plus d'inodes), vous pouvez exécuter cette requête: 

for i in `find . -type d `; do echo `ls -a $i | wc -l` $i; done | sort -n

comme un initié l'a mentionné dans une autre réponse, utiliser une solution avec find sera beaucoup plus rapide car ls récursif est assez lent, vérifiez ci-dessous cette solution! (crédit si le crédit est dû!)

82
Hannes

Les méthodes fournies avec les méthodes ls récursives sont très lentes . Juste pour trouver rapidement le répertoire parent qui consomme le plus d’inodes j’ai utilisé:

cd /partition_that_is_out_of_inodes
for i in *; do echo -e "$(find $i | wc -l)\t$i"; done | sort -n
37
insider

J'ai utilisé ce qui suit pour expliquer (avec l'aide de mon collègue James) que nous avions un grand nombre de fichiers de session PHP qui devaient être supprimés sur une seule machine:

1. Combien d'inodes ai-je utilisé?

 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. Où sont tous ces inodes?

 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:/#

Cela fait beaucoup de fichiers de session PHP sur la dernière ligne.

3. Comment supprimer tous ces fichiers?

Supprimez tous les fichiers du répertoire datant de plus de 1440 minutes (24 heures):

root@polo:/var/lib/php5/session# find ./ -cmin +1440 | xargs rm
root@polo:/var/lib/php5/session#

4. Cela a-t-il fonctionné?

 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:~#

Heureusement, nous avons reçu une alerte sensu nous informant que nos inodes étaient presque épuisés.

11
Sam Critchley

Ceci est mon point de vue sur elle. Ce n'est pas si différent des autres, mais le résultat est joli et je pense qu'il compte plus d'inodes valides que d'autres (répertoires et liens symboliques). Ceci compte le nombre de fichiers dans chaque sous-répertoire du répertoire de travail; il trie et formate la sortie en deux colonnes; et il affiche un total général (indiqué par ".", le répertoire de travail). Cela ne suivra pas les liens symboliques mais comptera les fichiers et les répertoires commençant par un point. Cela ne compte pas les nœuds de périphérique et les fichiers spéciaux tels que les canaux nommés. Supprimez simplement le test "-type l -o -type d -o -type f" si vous souhaitez également les compter. Cette commande étant divisée en deux commandes find, elle ne peut pas distinguer correctement les répertoires montés sur d'autres systèmes de fichiers (l'option -mount ne fonctionnera pas). Par exemple, cela devrait vraiment ignorer les répertoires "/ proc" et "/ sys". Vous pouvez voir que, dans le cas de l'exécution de cette commande dans "/", y compris "/ proc" et "/ sys", déforme grossièrement le nombre total.

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

Exemple:

# 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
10
Noah Spurrier

Voici un script Perl simple qui le fera:

#!/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 vous voulez que cela fonctionne comme du (où chaque compte de répertoire inclut également le compte récursif du sous-répertoire), changez la fonction récursive en return $count puis, au point de récurrence, dites:

$count += count_inodes($path) if (-d $path);
6
Alnitak
 pour i dans le répertoire [01] 
 do 
 find $ i -printf "% i\n" | sort -u | wc -l | xargs echo $ i --
 done 

dir.0 - 27913
dir.1 - 27913

1

utilisation 

ncdu -x <path>

puis appuyez sur Shitf + c pour trier par nombre d'éléments où l'élément est un fichier

1
LPby

Le script Perl est bon, mais méfiez-vous des liens symboliques: ne renvoyez-le-infirmer que si -l fichier est retourné, sinon, au mieux, vous le sur-compterez, au pire, indéfiniment (ce qui pourrait poser un problème mineur: invoquer le règne de 1000 ans de Satan).

L’idée de compter les inodes dans une arborescence de système de fichiers s’écroule s’il existe plusieurs liens vers plus d’un faible pourcentage des fichiers.

0
stinkoid

Cela compte les fichiers dans le répertoire courant. Ceci est supposé fonctionner même si les noms de fichiers contiennent des nouvelles lignes. Il utilise GNU Awk. Modifiez la valeur de d pour obtenir les profondeurs de chemin séparées maximales souhaitées. 0 signifie profondeur illimitée.

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

Idem pour Bash 4; c'est beaucoup plus lent dans mon expérience:

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 
0
jarno

Juste une note, lorsque vous trouvez enfin un répertoire de spool de courrier et que vous voulez supprimer tous les fichiers indésirables, rm * ne fonctionnera pas s'il y a trop de fichiers, vous pouvez exécuter la commande suivante pour supprimer rapidement tout ce qui se trouve dans ce répertoire:

* AVERTISSEMENT * CECI SUPPRIMERA TOUS LES FICHIERS RAPIDEMENT POUR LES CAS OCCASIONNÉS.

find . -type f -delete
0
CO4 Computing

Je voulais juste mentionner que vous pouvez également rechercher indirectement en utilisant la taille du répertoire, par exemple:

find /path -type d -size +500k

Où 500k pourrait être augmenté si vous avez beaucoup de grands annuaires.

Notez que cette méthode est pas récursive. Cela ne vous aidera que si vous avez beaucoup de fichiers dans un seul répertoire, mais pas si les fichiers sont répartis uniformément sur ses descendants.

0
Romuald Brunet