Answers:
我在stackoverflow上看到了这个问题,但是我不喜欢任何答案,无论如何,这确实是应该在U&L上提出的问题。
基本上,索引节点用于文件系统上的每个文件。因此,用尽inode通常意味着您周围有很多小文件。因此问题就变成了“哪个目录中包含大量文件?”
在这种情况下,我们关心的文件系统是根文件系统/
,因此我们可以使用以下命令:
find / -xdev -printf '%h\n' | sort | uniq -c | sort -k 1 -n
这将转储文件系统上每个目录的列表,并以该目录中文件(和子目录)的数量为前缀。因此,文件数量最多的目录将位于底部。
以我为例,它显示以下内容:
1202 /usr/share/man/man1
2714 /usr/share/man/man3
2826 /var/lib/dpkg/info
306588 /var/spool/postfix/maildrop
因此,基本上/var/spool/postfix/maildrop
是在消耗所有inode。
请注意,这个答案确实有三个需要注意的警告。它不能正确处理路径中带有换行符的任何内容。我知道我的文件系统没有带换行符的文件,并且由于该文件仅用于人类消费,因此潜在的问题不值得解决(并且始终可以\n
用\0
和替换sort -z
上面的)。如果文件分散在大量目录中,它也不会处理。但这不太可能,因此我认为风险可以接受。它还会多次计数到同一文件的硬链接(因此仅使用一个inode)。同样,不太可能产生误报
我不喜欢关于stackoverflow答案的任何答案的主要原因是它们都跨越了文件系统边界。由于我的问题是在根文件系统上,所以这意味着它将遍历每个已挂载的文件系统。投掷-xdev
在查找命令甚至没有正常工作。
例如,最受好评的答案是这个:
for i in `find . -type d `; do echo `ls -a $i | wc -l` $i; done | sort -n
如果我们改为
for i in `find . -xdev -type d `; do echo `ls -a $i | wc -l` $i; done | sort -n
即使/mnt/foo
是坐骑,它也是根文件系统上的目录,因此它将出现在中find . -mount -type d
,然后将其传递到ls -a $i
,然后将潜入坐骑。
将find
在我的答案,而不是列出了安装的每一个文件的目录。因此基本上具有以下文件结构:
/foo/bar
/foo/baz
/pop/tart
我们最终以
/foo
/foo
/pop
因此,我们只需要计算重复行的数量即可。
/tmp
,然后将系统配置为在上安装tmpfs /tmp
。这样一来,您将无法单独找到文件find
。不太可能是senario,但值得注意。
-printf
似乎是要查找的GNU扩展,因为OS X中可用的BSD版本不支持它。
这是按质询者的要求从此处转贴的:
du --inodes -S | sort -rh | sed -n \
'1,50{/^.\{71\}/s/^\(.\{30\}\).*\(.\{37\}\)$/\1...\2/;p}'
如果要保留在同一文件系统中,请执行以下操作:
du --inodes -xS
这是一些示例输出:
15K /usr/share/man/man3
4.0K /usr/lib
3.6K /usr/bin
2.4K /usr/share/man/man1
1.9K /usr/share/fonts/75dpi
...
519 /usr/lib/python2.7/site-packages/bzrlib
516 /usr/include/KDE
498 /usr/include/qt/QtCore
487 /usr/lib/modules/3.13.6-2-MANJARO/build/include/config
484 /usr/src/linux-3.12.14-2-MANJARO/include/config
一些人提到他们没有最新的coreutils,并且--inodes选项对他们不可用。所以,这是ls:
ls ~/test -AiR1U |
sed -rn '/^[./]/{h;n;};G;
s|^ *([0-9][0-9]*)[^0-9][^/]*([~./].*):|\1:\2|p' |
sort -t : -uk1.1,1n |
cut -d: -f2 | sort -V |
uniq -c |sort -rn | head -n10
如果您很好奇,那么麻烦的一点儿麻烦regex
就是将filename
每个ls's
递归搜索结果中的替换为找到它的目录名称。从那里,只需压缩重复的索引节点编号,然后计算重复的目录名称并进行相应排序即可。
该-U
选项与在分拣特别有用的是它专门针对没有进行排序,而是提出在原来的顺序目录列表-或者,换句话说,通过inode
数。
当然-1
,这非常有用,因为它可以确保每行只有一个结果,而不管文件名中可能包含换行符,还是尝试解析列表时可能发生的其他不幸的问题。
当然,-A
对于所有人,-i
inode和-R
递归来说,这都是长短。
这样做的基本方法是,我将ls的每个文件名替换为sed中包含目录名称的文件名。接下来……好吧,我自己有点模糊。我可以肯定,它可以准确计数文件,如您在此处看到的:
% _ls_i ~/test
> 100 /home/mikeserv/test/realdir
> 2 /home/mikeserv/test
> 1 /home/mikeserv/test/linkdir
这为我提供了与du
命令几乎相同的结果:
15K /usr/share/man/man3
4.0K /usr/lib
3.6K /usr/bin
2.4K /usr/share/man/man1
1.9K /usr/share/fonts/75dpi
1.9K /usr/share/fonts/100dpi
1.9K /usr/share/doc/arch-wiki-markdown
1.6K /usr/share/fonts/TTF
1.6K /usr/share/dolphin-emu/sys/GameSettings
1.6K /usr/share/doc/efl/html
14686 /usr/share/man/man3:
4322 /usr/lib:
3653 /usr/bin:
2457 /usr/share/man/man1:
1897 /usr/share/fonts/100dpi:
1897 /usr/share/fonts/75dpi:
1890 /usr/share/doc/arch-wiki-markdown:
1613 /usr/include:
1575 /usr/share/doc/efl/html:
1556 /usr/share/dolphin-emu/sys/GameSettings:
我认为include
事情只取决于程序首先查看哪个目录-因为它们是相同的文件,并且经过硬链接。有点喜欢上面的事情。我对此可能是错的-我欢迎改正...
% du --version
> du (GNU coreutils) 8.22
创建一个测试目录:
% mkdir ~/test ; cd ~/test
% du --inodes -S
> 1 .
一些子目录:
% mkdir ./realdir ./linkdir
% du --inodes -S
> 1 ./realdir
> 1 ./linkdir
> 1 .
制作一些文件:
% printf 'touch ./realdir/file%s\n' `seq 1 100` | . /dev/stdin
% du --inodes -S
> 101 ./realdir
> 1 ./linkdir
> 1 .
一些硬链接:
% printf 'n="%s" ; ln ./realdir/file$n ./linkdir/link$n\n' `seq 1 100` |
. /dev/stdin
% du --inodes -S
> 101 ./realdir
> 1 ./linkdir
> 1 .
查看硬链接:
% cd ./linkdir
% du --inodes -S
> 101
% cd ../realdir
% du --inodes -S
> 101
他们一个人算,但上一个目录...
% cd ..
% du --inodes -S
> 101 ./realdir
> 1 ./linkdir
> 1 .
然后从下面运行我的运行脚本,然后:
> 100 /home/mikeserv/test/realdir
> 100 /home/mikeserv/test/linkdir
> 2 /home/mikeserv/test
和格雷姆的:
> 101 ./realdir
> 101 ./linkdir
> 3 ./
因此,我认为这表明计数inode的唯一方法是使用inode。而且,由于对文件进行计数意味着对inode进行计数,因此您不能对inode进行双重计数-要对文件进行精确计数,就不能对inode进行多次计数。
--inodes
?哪个“变体” /“风味” /“ posix-wannabes” /“实现” /什么?
我使用了SO Q&A中题为:我的所有inode都在哪里使用的答案?当我们的NAS大约2年前用完时:
$ find . -type d -print0 \
| while IFS= read -rd '' i; do echo $(ls -a "$i" | wc -l) "$i"; done \
| sort -n
$ find . -type d -print0 \
| while IFS= read -rd '' i; do echo $(ls -a "$i" | wc -l) "$i"; done \
| sort -n
...
110 ./MISC/nodejs/node-v0.8.12/out/Release/obj.target/v8_base/deps/v8/src
120 ./MISC/nodejs/node-v0.8.12/doc/api
123 ./apps_archive/monitoring/nagios/nagios-check_sip-1.3/usr/lib64/nagios
208 ./MISC/nodejs/node-v0.8.12/deps/openssl/openssl/doc/crypto
328 ./MISC/nodejs/node-v0.8.12/deps/v8/src
453 ./MISC/nodejs/node-v0.8.12/test/simple
根据您的NAS,它可能无法提供功能齐全的df
命令。因此,在这些情况下,您可以改为使用tune2fs
:
$ sudo tune2fs -l /dev/sda1 |grep -i inode
Filesystem features: has_journal ext_attr resize_inode dir_index filetype needs_recovery extent flex_bg sparse_super huge_file uninit_bg dir_nlink extra_isize
Inode count: 128016
Free inodes: 127696
Inodes per group: 2032
Inode blocks per group: 254
First inode: 11
Inode size: 128
Journal inode: 8
Journal backup: inode blocks
您可以使用-xdev
开关直接find
将搜索范围缩小到您要启动搜索的设备。
假设我/home
通过我的NAS(名称为mulder)通过NFS共享进行目录自动挂载。
$ df -h /home/sam
Filesystem Size Used Avail Use% Mounted on
mulder:/export/raid1/home/sam
917G 572G 299G 66% /home/sam
注意,安装点仍被认为是系统本地的。
$ df -h /home/ .
Filesystem Size Used Avail Use% Mounted on
- 0 0 0 - /home
/dev/mapper/VolGroup00-LogVol00
222G 159G 52G 76% /
现在当我启动时find
:
$ find / -xdev | grep '^/home'
/home
它发现/home
但没有自动装入的内容,因为它们位于不同的设备上!
您可以利用切换到find
,-fstype
以控制find
将查找哪种类型的文件系统。
-fstype type
File is on a filesystem of type type. The valid filesystem types
vary among different versions of Unix; an incomplete list of
filesystem types that are accepted on some version of Unix or
another is: ufs, 4.2, 4.3, nfs, tmp, mfs, S51K, S52K. You can use
-printf with the %F directive to see the types of your
filesystems.
我有什么文件系统?
$ find . -printf "%F\n" | sort -u
ext3
因此,您可以使用它来控制交叉路口:
仅ext3
$ find . -fstype ext3 | head -5
.
./gdcm
./gdcm/gdcm-2.0.16
./gdcm/gdcm-2.0.16/Wrapping
./gdcm/gdcm-2.0.16/Wrapping/CMakeLists.txt
只有nfs
$ find . -fstype nfs | head -5
$
ext3和ext4
$ find . -fstype ext3 -o -fstype ext4 | head -5
.
./gdcm
./gdcm/gdcm-2.0.16
./gdcm/gdcm-2.0.16/Wrapping
./gdcm/gdcm-2.0.16/Wrapping/CMakeLists.txt
/
是否已满,并且已经安装了网络文件系统一样,您不想深入研究网络文件系统。
-fstype
来控制它find
。
-xtype
排除文件系统,而是查看文件的类型。我只找到这样的示例:find . \( -fstype nfs -prune \)
find
避免越过文件系统边界的评论中谈到了Patrick的问题。在他的前任。他提到“就像/如果已满,并且您已经安装了网络文件系统,就不想深入研究网络文件系统”。
查找使用的inode的命令:
for i in /*; do echo $i; find $i |wc -l | sort ; done
绝对最多的回答可以帮助理解linux和unix中的inode的概念,但是当涉及到从磁盘删除或删除inode的实际问题时,它并没有真正的帮助。在基于ubuntu的系统上执行此操作的一种更简单的方法是删除不需要的linux内核标头和映像。
sudo apt-get autoremove
会为你做的。就我而言,由于收到警报,因此inode的使用率为78%。
$ df -i
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/xvda1 524288 407957 116331 78% /
none 957443 2 957441 1% /sys/fs/cgroup
udev 956205 388 955817 1% /dev
tmpfs 957443 320 957123 1% /run
none 957443 1 957442 1% /run/lock
none 957443 1 957442 1% /run/shm
none 957443 5 957438 1% /run/user
运行sudo apt-get autoremove
命令后,它已下降到29%
$ df -i
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/xvda1 524288 150472 373816 29% /
none 957443 2 957441 1% /sys/fs/cgroup
udev 956205 388 955817 1% /dev
tmpfs 957443 320 957123 1% /run
none 957443 1 957442 1% /run/lock
none 957443 1 957442 1% /run/shm
none 957443 5 957438 1% /run/user
这只是我的观察,节省了我的时间。人们可能会找到比这更好的解决方案。
到目前为止,每个答案都假定问题出在单个目录中有许多文件,而不是所有导致问题的子目录中。幸运的是,解决方案是仅使用更少的标志。
# du --inodes --one-file-system /var | sort --numeric-sort
...
2265 /var/cache/salt/minion
3818 /var/lib/dpkg/info
3910 /var/lib/dpkg
4000 /var/cache/salt/master/gitfs/refs
4489 /var/lib
5709 /var/cache/salt/master/gitfs/hash
12954 /var/cache/salt/master/gitfs
225058 /var/cache/salt/master/jobs
241678 /var/cache/salt/master
243944 /var/cache/salt
244078 /var/cache
248949 /var
或更短的选项:du --inodes -x | sort -n
。不幸的是,并非所有版本都du
具有inodes选项。