web-dev-qa-db-ja.com

すべてのiノードはどこで使用されていますか?

どのディレクトリがすべてのiノードを噛み砕くのかを調べるにはどうすればよいですか?

最終的にはルートディレクトリが最大数のiノードを担当するため、どのような答えが必要か正確にはわかりません。

基本的に、使用可能なiノードが不足しているため、カリングするために不要なディレクトリを見つける必要があります。

あいまいな質問をありがとう。

51
Joel

基本的に、どのディレクトリに多くのファイルがあるかを探していますか?ここに最初の突き刺しがあります:

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

ここで、「count_files」はこれを行うシェルスクリプトです(ありがとうJonathan)

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

新しいファイルを作成したくない場合(またはiノードを使い果たしたために作成できない場合)、次のクエリを実行できます。

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

インサイダーが別の回答で言及したように、再帰的なlsは非常に遅いため、findを使用したソリューションの使用ははるかに高速になります。そのソリューションについては以下を確認してください。 (クレジットが必要な場合はクレジット!)

82
Hannes

再帰的lsで提供されるメソッドは非常に遅いです。使用したiノードのほとんどを消費する親ディレクトリをすばやく見つけるためだけに:

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

私は、同僚のジェームズの助けを借りて、次のコードを使用して、1台のマシンで削除する必要があるPHPセッションファイルが大量にあったことを確認しました。

1。いくつのiノードを使用していますか?

 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。これらのすべてのiノードはどこにありますか?

 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セッションファイル。

。それらすべてのファイルを削除する方法?

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

幸いなことに、iノードがほとんど使い果たされたことを通知するsensuアラートがありました。

12
Sam Critchley

これは私の考えです。他のものとそれほど違いはありませんが、出力はきれいで、他のもの(ディレクトリとシンボリックリンク)よりも有効なiノードをカウントしていると思います。これは、作業ディレクトリの各サブディレクトリ内のファイルの数をカウントします。出力をソートして2列にフォーマットします。そして、総計( "。"、作業ディレクトリとして表示)を出力します。これはシンボリックリンクをたどりませんが、ドットで始まるファイルとディレクトリをカウントします。これは、デバイスノードと名前付きパイプなどの特殊ファイルをカウントしません。それらもカウントする場合は、「-type l -o -type d -o -type f」テストを削除します。このコマンドは2つの検索コマンドに分割されているため、他のファイルシステムにマウントされているディレクトリを正しく識別することはできません(-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
10
Noah Spurrier

これを行う簡単な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);
6
Alnitak

実際に機能するワンライナー(GNU find、他の種類の検索では、同じFSにとどまるために_-xdev_と同等の独自のものが必要です)

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_

4
AnrDaemon
 for i for dir。[01] 
 do 
 find $ i -printf "%i\n" | sort -u | wc -l | xargs echo $ i- 
完了

dir.0-27913
dir.1-27913

1

つかいます

ncdu -x <path>

次に、Shitf + cを押して、アイテムがファイルのある場所のアイテム数でソートします

1
LPby

Perlスクリプトは優れていますが、シンボリックリンクに注意してください--l filetestがfalseを返す場合にのみ再帰するか、せいぜいオーバーカウント、最悪の場合は無期限に再帰します(これはささいな懸念ではありませんが、サタンの1000年の治世を引き起こす可能性があります)。

ファイルシステムツリー内のiノードをカウントするという考え全体は、ごく一部のファイルへの複数のリンクがある場合にばらばらになります。

0
stinkoid

これは、現在のディレクトリの下のファイルをカウントします。これは、ファイル名に改行が含まれている場合でも機能するはずです。 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 
0
jarno

注:最後にメールスプールディレクトリを見つけて、そこにあるすべてのジャンクを削除したい場合、ファイルが多すぎるとrm *は機能しません。次のコマンドを実行して、そのディレクトリ内のすべてをすばやく削除できます。

*警告*これは、rmが機能しない場合に、すべてのファイルをすばやく削除します

find . -type f -delete
0
CO4 Computing

たとえば、ディレクトリサイズを使用して間接的に検索することもできます。

find /path -type d -size +500k

大きなディレクトリがたくさんある場合、500kを増やすことができます。

このメソッドはnot再帰的であることに注意してください。これは、単一のディレクトリに多数のファイルがある場合にのみ役立ちますが、ファイルがその子孫に均等に分散されている場合には役立ちません。

0
Romuald Brunet