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.
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
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û!)
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
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.
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
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);
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
utilisation
ncdu -x <path>
puis appuyez sur Shitf + c pour trier par nombre d'éléments où l'élément est un fichier
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.
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
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
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.