stat命令是唯一能一次性获取文件真实底层inode元数据的工具,输出的inode、links、access/modify/change时间等字段直接来自磁盘inode表,非推算所得;-c选项支持结构化输出,-f用于查文件系统级inode总量与剩余量,-l可解析符号链接目标。

stat 命令能直接读取 inode 元数据,不是“增强版 ls”,而是唯一能一次性拿到真实底层属性的工具。它输出的 Inode、Links、Change 时间等字段,是文件系统实际维护的字段,不是推算出来的。
查文件基础属性:别只看默认输出,先确认字段含义
执行 stat /etc/hosts 会输出一堆字段,但真正关键的是三类时间戳和硬链接数:
-
Access:最后一次读取内容的时间(如cat、grep),但受挂载选项noatime影响,可能长期不更新 -
Modify:最后一次修改文件「内容」的时间(如echo >>、vim保存),最常用于判断数据是否变更 -
Change:最后一次修改「元数据」的时间(如chmod、chown、重命名),比Modify更敏感,容易误判为“内容被改” -
Links:硬链接数,若为0,说明文件已被删除但仍有进程在读写(即“已删未释放”,常见于日志轮转后)
用 -c 定制输出:避免解析默认文本,直接提取结构化字段
默认输出是人类可读格式,不适合脚本处理。用 -c 可精确控制字段和顺序,且支持批量:
-
stat -c "%n %s %y" /var/log/syslog→ 输出:文件名、字节大小、Modify时间(ISO 格式) -
stat -c "%i %a %U:%G" /tmp/file→ 输出:inode 号、八进制权限、所有者:组名 - 批量处理多个文件:
stat -c "%n %s %y" *.log(shell 自动展开,安全;含空格也不崩) - 配合
find更稳妥:find /var/log -name "*.log" -print0 | xargs -0 stat -c "%n %s %y"
查 inode 和文件系统状态:-f 和 -L 不能混用
stat 的两个核心场景是查单个文件元数据,和查整个文件系统状态,参数互斥:
- 查文件 inode 编号、硬链接数、块分配等:
stat /etc/passwd或stat -c "%i %h %b %B" /etc/passwd(%h是硬链接数,%b是占用块数,%B是块字节数) - 查文件系统级信息(如 inode 总量、剩余量):
stat -f /,输出里Total、Free、Available对应 inode 统计,比df -i多一层设备细节 - 查符号链接目标文件(而非链接本身):
stat -L /path/to/symlink;不加-L默认显示链接文件自己的 inode 和权限
“创建时间”为什么总是 -?这不是 bug,是文件系统限制
执行 stat -c "%w" /tmp/test 如果输出 - 或空,说明当前文件系统(ext4 或默认 XFS)根本没存创建时间(Birth time)。这不是命令问题,而是设计如此:
- ext4 默认不启用 birth 字段;XFS 需开启
file creation time特性且内核 ≥5.10,发行版几乎都关闭 -
stat输出里的Birth:行只是占位符,不可靠;生产环境逻辑别依赖它 - 替代方案:用
debugfs -R "stat <inode>" /dev/sdX</inode>(ext4,需 root)或xfs_info(XFS),但结果不稳定,仅调试用 - 真正可用的锚点只有
Modify时间,或日志文件名里自带的时间戳(如app-20260612.log)
最容易被忽略的是 Change 时间和 Links 字段的组合意义:一个文件 Modify 没变但 Change 更新了,大概率是权限或所有者被改过;Links 为 0 则意味着磁盘空间没释放,得找对应进程 lsof +L1 才能清理。











