ls显示文件逻辑大小(st_size),du统计物理磁盘占用(实际分配块),二者差异源于数据来源不同:ls读inode的st_size,du遍历已分配数据块并跳过空洞。

ls 显示的是文件的逻辑大小(st_size),du 统计的是物理磁盘占用(实际分配的块)——两者不一致不是 bug,而是文件系统设计使然。
为什么 ls -l 和 du -h 显示的大小经常对不上
根本原因是它们读取的数据来源完全不同:ls -l 直接从 inode 的 st_size 字段取值,即你“写进去多少字节”;而 du 会遍历文件实际占用的数据块,跳过空洞、只算已分配的部分。
- 稀疏文件(如
dd if=/dev/zero of=img bs=1M seek=1024 count=0创建的镜像):ls -lh显示 1.0G,du -h可能只报 200K - 小文件(比如 1 字节):
ls -l显示 1,du -h显示 4.0K(一个 4KB 块) - 目录本身:
ls -ld显示 4.0K(目录项元数据大小),du -sh显示的是该目录下所有内容总占用 - 硬链接:
ls对每个链接都显示完整逻辑大小;du默认去重统计(同一 inode 只算一次),除非加-l
du 的 --apparent-size 是什么作用
这个选项让 du 改用 st_size 而非块占用做计算,结果就和 ls 一致了。它适合需要“按内容长度汇总”的场景,比如估算备份数据量(而非磁盘开销)。
Linux 安全审计工具,检查 SSH 配置、开放/监听端口、防火墙规则(ufw/iptables/nftables)、失败登录尝试、sudoers 权限...
- 对比示例:
du -h large_sparse_file→ 输出 12Mdu -h --apparent-size large_sparse_file→ 输出 2.1G(接近ls -lh) - 注意:
--apparent-size不影响硬链接去重逻辑,仍需配合-l才会把每个硬链接都单独计入 - 在脚本中批量处理时,若目标是统计“总写入字节数”,应优先用此选项,避免被空洞误导
stat 命令怎么看逻辑大小和块数
stat 是最直接验证两者的工具,它同时展示 Size(逻辑大小)和 Blocks(实际分配的 512 字节块数),还能看到 IO Block(文件系统块大小)。
- 执行
stat example.txt,关键字段如下:
Size: 1048576→ 逻辑大小 1MB
Blocks: 2048→ 实际占用了 2048 × 512 = 1MB(无空洞)
IO Block: 4096→ 文件系统以 4KB 为单位分配 - 若
Blocks × 512 ,说明是稀疏文件(存在空洞) -
stat -c "%s %b %B" file可脚本化提取:分别输出st_size、块数、块大小(单位字节)
生产环境里最容易忽略的一点
监控脚本或日志轮转逻辑如果只依赖 ls -l 判断文件是否“过大”,可能漏掉真实磁盘压力;反过来,只看 du 又可能低估备份传输量。真正的判断依据得结合场景选指标:看磁盘是否快满?用 du;看某次写入是否超限?用 stat 或 ls 的 st_size;不确定时,两个都查。

















