存储分析基础:df/du命令详解、分析rootfs各目录大小、找出存储占用大户

做rootfs裁剪,第一步不是动手删文件。

你得先搞清楚——空间到底去哪了?

我见过不少新手,上来就对着/lib一顿乱删,结果系统起不来。嗯,这种事我也干过。后来学乖了,先分析,再动手。今天我们就来聊聊存储分析的两个核心工具:df和du,以及怎么用它们把rootfs的存储账本查清楚。

2.1 df:先看全局,再下刀

df(disk free)看的是文件系统级别的空间使用情况。说白了,它告诉你每个分区还剩多少空间,挂载点在哪。

我个人习惯,第一步永远是:

df -h

-h参数以人类可读的格式(K、M、G)显示。输出大概长这样:

Filesystem      Size  Used Avail Use% Mounted on
/dev/root       2.0G  1.8G  200M  90% /
devtmpfs        256M     0  256M   0% /dev
tmpfs           256M     0  256M   0% /dev/shm
tmpfs            50M  1.2M   49M   3% /run
tmpfs           5.0M     0  5.0M   0% /run/lock

看到/dev/root这一行了吗?Use% 90%,这就是我们裁剪的目标。根分区总共2GB,已经用了1.8GB,只剩200MB。如果你做的是产品,这个数字超过80%就该拉警报了。

注意:有些嵌入式系统会把rootfs做成只读的squashfs或erofs。这时候df看到的Used是压缩后的尺寸,实际解压后占用更大。别被数字骗了。

还有一个参数我经常用:df -h --total。它会在最后加一行总计,方便你快速评估整体存储压力。

2.2 du:逐层深挖,定位元凶

df告诉你分区满了,但没告诉你是谁吃的。这时候du(disk usage)上场。

du递归统计目录和文件的磁盘占用。我最常用的组合是:

du -sh /usr /lib /etc /var /opt /home /root /boot

-s只显示总计,-h人类可读。输出:

1.2G    /usr
400M    /lib
120M    /var
 50M    /etc
 30M    /opt
 10M    /home
  8M    /root
  5M    /boot

一目了然。/usr占了1.2GB,/lib占了400MB。这两个目录加起来就占了总空间的绝大部分。裁剪的重点,基本就在它们身上。

但别停在这里。我们得继续往下挖:

du -sh /usr/* | sort -rh | head -10

这条命令列出/usr下所有子目录的大小,按从大到小排序,取前10个。输出:

500M    /usr/share
400M    /usr/lib
200M    /usr/bin
100M    /usr/include
 50M    /usr/sbin
 30M    /usr/local
 20M    /usr/src
 10M    /usr/games

你看,/usr/share和/usr/lib是最大的两个。再往下挖:

du -sh /usr/share/* | sort -rh | head -10

这样一层层剥下去,你就能找到那些“存储大户”。

我的习惯:每次分析都从根目录开始,逐层深入。不要跳级,否则容易漏掉隐藏的大文件。我曾经在/var/log里发现一个300MB的日志文件,差点把根分区撑爆。

2.3 实战:分析rootfs各目录典型大小

不同嵌入式系统的rootfs大小差异很大。但一般来说,各目录的典型占用范围如下:

目录 典型大小 说明
/usr 500MB - 2GB 用户程序、库、文档、locale。裁剪重灾区
/lib 100MB - 500MB 核心动态库、内核模块。动之前想清楚
/var 50MB - 500MB 日志、缓存、临时数据。经常被忽视的膨胀源
/etc 10MB - 100MB 配置文件。一般不大,但别乱删
/opt 0 - 500MB 第三方软件。很多产品不用,可以直接去掉
/boot 5MB - 50MB 内核、dtb、initramfs。大小相对固定
/home 0 - 10MB 嵌入式系统通常为空,可忽略
/root 0 - 10MB root用户家目录,通常很小

你想想看,如果你的rootfs总共只有2GB,/usr就占了1.2GB,那/usr/share里的locale、help文档、图标这些“非必需品”就是首要裁剪对象。

2.4 找出存储占用大户的完整流程

我总结了一套标准流程,每次做裁剪分析都这么走:

  1. 全局扫描:df -h,确认哪个分区满了。
  2. 一级目录扫描:du -sh /* | sort -rh,找出最大的几个目录。
  3. 逐层深入:对每个大目录,重复du -sh <dir>/* | sort -rh | head -10,直到找到具体的大文件或大目录。
  4. 记录异常:把超过预期大小的目录记下来,后面裁剪时重点关注。
  5. 交叉验证:用find / -type f -size +10M -exec ls -lh {} \;找出所有大于10MB的文件,看看有没有漏网之鱼。
核心原则:先分析,后动手。每次只改一个点,验证一次。不要批量删除,否则出了问题你都不知道是哪一刀砍错了。

2.5 知识体系:存储分析核心逻辑

下面这张图,把整个存储分析的逻辑串起来了。建议你收藏,每次做裁剪前看一眼。

rootfs存储分析核心流程 rootfs存储分析核心流程 df -h 全局扫描 du -sh /* 一级目录 逐层 du -sh 深入 记录存储占用大户 find 交叉验证 关键命令速查 df -h du -sh /dir/* sort -rh head -10 find / -size +10M 常用参数: -h 人类可读 -s 只显示总计 --max-depth=N 避坑: 先分析,后动手 每次只改一个点 验证后再继续

这个流程我用了好多年,从没出过问题。你照着走一遍,rootfs里哪些东西能吃、哪些不能碰,心里就有数了。

2.6 避坑指南:我踩过的几个坑

最后分享几个实战中遇到的坑,你遇到了能少走弯路:

  • 硬链接重复计数:du默认会把硬链接的每个引用都算一次大小。用du -l可以避免重复统计。我曾经被这个坑过,以为某个目录占了500MB,实际只有100MB。
  • 稀疏文件:有些文件看起来很大,但实际占用的磁盘空间很小。用du看的是实际占用,ls -l看的是文件大小。两者不一致时,别慌。
  • 挂载点干扰:如果你在rootfs里挂载了其他分区(比如/mnt),du会递归进去统计。用-x参数可以限制只统计当前文件系统。
  • /proc和/sys:这两个是虚拟文件系统,du统计它们没有意义。直接跳过。
重要提醒:不要在目标设备上直接运行du -sh /。它会遍历整个文件系统,在低端嵌入式设备上可能跑几分钟甚至卡死。我建议在开发主机上对rootfs目录树进行分析,或者用--max-depth=1限制深度。