Где используются все мои иноды? - PullRequest
51 голосов
/ 07 декабря 2008

Как мне узнать, какие каталоги отвечают за разжевывание всех моих инодов?

В конечном итоге корневой каталог будет отвечать за наибольшее количество инодов, поэтому я не уверен, какой именно ответ мне нужен.

Обычно у меня заканчиваются доступные иноды, и мне нужно найти ненужный каталог для отбраковки.

Спасибо, извините за смутный вопрос.

Ответы [ 14 ]

82 голосов
/ 21 января 2012

Если вы не хотите создавать новый файл (или не можете, потому что у вас закончились иноды), вы можете выполнить этот запрос:

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

Как сказал инсайдер в другом ответе, использование решения с поиском будет намного быстрее, поскольку рекурсивный ls довольно медленный, проверьте ниже это решение! (кредит при условии кредита!)

38 голосов
/ 18 января 2013

Предоставленные методы с рекурсией ls очень медленные. Просто для быстрого поиска родительского каталога, потребляющего большинство используемых мной инодов:

cd /partition_that_is_out_of_inodes
for i in *; do echo -e "$(find $i | wc -l)\t$i"; done | sort -n
20 голосов
/ 07 декабря 2008

Итак, в основном вы ищете, в каких каталогах много файлов? Вот первый удар по нему:

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

где "count_files" - это скрипт оболочки, который выполняет (спасибо Джонатану)

echo $(ls -a "$1" | wc -l) $1
12 голосов
/ 29 мая 2015

Я использовал следующее, чтобы выяснить (с небольшой помощью моего коллеги Джеймса), что у нас было огромное количество файлов сеансов PHP, которые нужно было удалить на одной машине:

1. Сколько инодов я использовал?

 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. Где все эти иноды?

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

Это много файлов сессий PHP в последней строке.

3. Как удалить все эти файлы?

Удалить все файлы в каталоге старше 1440 минут (24 часа):

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

4. Это сработало?

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

К счастью, у нас было уведомление от Sensu, в котором сообщалось, что наши иноды почти израсходованы.

10 голосов
/ 08 января 2014

Это мое мнение. Это не так сильно отличается от других, но вывод хорош, и я думаю, что он учитывает больше допустимых inode, чем другие (каталоги и символические ссылки). Это подсчитывает количество файлов в каждом подкаталоге рабочего каталога; сортирует и форматирует вывод в две колонки; и он печатает общий итог (отображается как «.», рабочий каталог). Это не будет следовать символическим ссылкам, но будет подсчитывать файлы и каталоги, которые начинаются с точки. Это не учитывает узлы устройства и специальные файлы, такие как именованные каналы. Просто удалите тест "-type l -o -type d -o -type f", если вы тоже хотите их посчитать. Поскольку эта команда разделена на две команды поиска, она не может правильно различать каталоги, смонтированные в других файловых системах (опция -mount не будет работать). Например, это должно действительно игнорировать каталоги "/ proc" и "/ sys". Вы можете видеть, что в случае запуска этой команды в "/", которая включает в себя "/ proc" и "/ sys", сильно искажается общий итог.

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

Пример:

# 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
6 голосов
/ 07 декабря 2008

Вот простой Perl-скрипт, который сделает это:

#!/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);
}

Если вы хотите, чтобы он работал как du (где каждый счетчик каталогов также включает в себя рекурсивный счетчик подкаталога), тогда измените рекурсивную функцию на return $count, а затем в точке рекурсии произнесите:

$count += count_inodes($path) if (-d $path);
3 голосов
/ 16 марта 2016

фактически функциональный однострочный (GNU find, для других типов поиска вам понадобится собственный эквивалент -xdev, чтобы остаться на той же FS.)

find / -xdev -type d | while read -r i; do printf "%d %s\n" $(ls -a "$i" | wc -l) "$i"; done | sort -nr | head -10

Хвост, очевидно, настраивается.

Как и во многих других предложениях здесь, это покажет вам только количество записей в каждом каталоге, не рекурсивно.

приписка

Быстрая, но неточная однострочная (определяется по размеру узла каталога):

find / -xdev -type d -size +100k

1 голос
/ 27 сентября 2017

использование

ncdu -x <path>

затем нажмите Shitf + c, чтобы отсортировать по количеству элементов, в которых находится файл

1 голос
/ 08 июня 2013
for i in dir.[01]
do
    find $i -printf "%i\n"|sort -u|wc -l|xargs echo $i --
done

dir.0 - 27913
реж. 1 - 27913

0 голосов
/ 08 сентября 2016

Это количество файлов в текущем каталоге. Это должно работать, даже если имена файлов содержат символы новой строки. Он использует GNU Awk. Измените значение d, чтобы получить желаемую максимальную глубину разделенного пути. 0 означает неограниченную глубину.

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

То же самое по Bash 4; это значительно медленнее в моем опыте:

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