情况描述
缘由:近期有被问到,如果 df -i 发现分区的inode满了,如何快速的找到inode数量最多的目录?
处理:这种情况是有碰到过的,一般就是小文件数量过多导致inode耗尽,解决办法就是找到并清理这些小文件
思考:由于处理的都是非常熟悉的服务器,都不需要额外分析就能找到大致的目录,所以并没有考虑说怎么去查找这个目录,不能大意呐
分析思路
首先inode满了,一般考虑是小文件太多,因为每个文件都会占用一个inode,所以查出inode占用最多的目录,其实就是找到文件数量最多的目录了。
那简单来说,就是例举所有文件了,这就分两种思路了:
- 一是获取分区的一层目录,然后获取每个目录下的所有文件数量,然后排序
- 二是列举所有文件,然后将从路径截取去掉文件名,然后排序
后续的内容,用 /home 目录测试
实现方式
方式一 例举目录 遍历文件
列举一层目录,递归查找文件,然后排序
1)查找第一层目录 默认会递归,需要控制深度1层
find /home -maxdepth 1 -type d
2)遍历目录获取文件数量 这里用sh -c 是因为 需要用到管道符
find -exec 的方式
find /home -maxdepth 1 -type d -exec sh -c 'echo `find {} -type f |wc -l` {} ' \;
xargs 的方式
find /home -maxdepth 1 -type d |xargs -i sh -c 'echo `find {} -type f |wc -l` {} '
3)排序
find /home -maxdepth 1 -type d |xargs -i sh -c 'echo `find {} -type f |wc -l` {} '|sort -nr
参数解释(man 里面有详细解释):
find
/home 需要遍历的目录,不建议用当前目录,当前目录遍历结果不是全路径
-maxdepth 1 遍历深度一层
-type d 查找目录类型
-type f 查找文件类型
-exec 对每一条记录执行的命令 {} 表示单条遍历结果,需要 \; 结尾
xargs
-i 用 {} 代替前面返回的输入,等价于 -I{},好处是可以自己制定参数位置
sh
-c 将后面的内容在shell执行,解决某些命令不支持管道符的问题
wc
-l 统计文本内容的行数
sort
-rn n按数字排序,r逆序
方式二 遍历文件 截取目录
AI 提供了另外一种方式,遍历文件,截取目录,排序,这种是更优解
find /home/ -maxdepth 2 -xdev -printf '%h\n' | sort | uniq -c|sort -rn
参数解析(man find):
find
-xdev 不要跨越文件系统遍历目录
-printf '%h\n' 格式化输出
%h 是指文件的目录(就是路径去掉文件名),如果不是/开头的,就按当前目录.显示
问题总结
其实按照直接解决问题的思路来说,拆分逐步解决是最直接的,但是并不一定是最高效的。
如有有时间,可以尝试看看有没有方案二。