Где используются все мои иноды?

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

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

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

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

Ответ 1

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

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

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

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

Ответ 2

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

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

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

Ответ 3

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

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

Ответ 4

Это мое занятие. Это не так сильно отличается от других, но результат довольно хорош, и я думаю, что он считает более допустимыми inodes, чем другие (каталоги и символические ссылки). Это подсчитывает количество файлов в каждом подкаталоге рабочего каталога; он сортирует и форматирует вывод в две колонки; и он печатает общую сумму (показанную как ".", рабочий каталог). Это не будет следовать символическим ссылкам, но будет считать файлы и каталоги, начинающиеся с точки. Это не означает узлы устройств и специальные файлы, например, именованные каналы. Просто удалите тест типа "-type -o-type d -o-type", если вы хотите их подсчитать. Поскольку эта команда разделена на две команды поиска, она не может правильно различать каталоги, установленные на других файловых системах (опция -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

Ответ 5

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

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

 [email protected]:/# 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. Где все эти иноды?

 [email protected]:/# 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
 [email protected]:/#

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

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

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

[email protected]:/var/lib/php5/session# find ./ -cmin +1440 | xargs rm
[email protected]:/var/lib/php5/session#

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

 [email protected]:~# 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
 [email protected]:~# 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
 [email protected]:~#

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

Ответ 6

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

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

Ответ 7

Фактически функциональный однострочный (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

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

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

P.S.

Быстрый, но неточный однострочный (определение по каталогу node):

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

Ответ 8

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

Ответ 9

Просто заметьте, когда вы, наконец, найдете какой-то почтовый спулер и хотите удалить все нежелательные файлы, которые там есть, rm * не будет работать, если файлов слишком много, вы можете запустить следующую команду, чтобы быстро удалить все в этом каталог:

* ПРЕДУПРЕЖДЕНИЕ * ЭТО УДАЛИТЬ ВСЕ ФАЙЛЫ БЫСТРО ДЛЯ СЛУЧАЙ, КОГДА rm НЕ РАБОТАЕТ

find . -type f -delete

Ответ 10

Perl script хорош, но будьте осторожны с symlinks-recurse только тогда, когда -l filetest возвращает false, или вы в лучшем случае перечитываете, в худшем случае, рекурсивно на неопределенное время (что может вызвать беспокойство - вызвать сатану 1000-летнее царствование).

Вся идея подсчета inodes в дереве файловой системы разваливается, когда имеется несколько ссылок на более чем небольшой процент файлов.

Ответ 11

Просто хотел упомянуть, что вы также можете искать косвенно, используя размер каталога, например:

find /path -type d -size +500k

Если 500k можно увеличить, если у вас много больших каталогов.

Обратите внимание, что этот метод не рекурсивный. Это поможет вам только в том случае, если у вас много файлов в одном каталоге, но не в том случае, если файлы распределены равномерно по своим потомкам.

Ответ 12

Это подсчитывает файлы в текущем каталоге. Это должно работать, даже если имена файлов содержат символы новой строки. Он использует 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 

Ответ 13

использовать

ncdu -x <path>

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

Ответ 14

Эта команда работает в очень маловероятных случаях, когда ваша структура каталогов идентична моей:

find / -type f | grep -oP '^/([^/]+/){3}' | sort | uniq -c | sort -n