stat 是什么
stat 来自 coreutils,一次读取 inode 与文件系统元数据:inode 号、权限位、硬链接数、属主属组、三个时间戳、字节大小、占用块数与文件系统块信息。ls -l 只给出其中一部分,stat 给的是全量,且可以用 -c 定制输出格式。判断「文件何时被改、是否被替换过、inode 有没有变、实际占了多少块」,都靠它。
基本信息
| 适用平台 | Linux(coreutils,默认自带) |
|---|---|
| 命令语法 | stat [选项] 文件... |
| 常用选项 | -c 自定义格式 -f 显示文件系统信息 -t 简洁一行 -L 跟随符号链接 |
| 常用格式符 | %n 文件名 %s 字节大小 %i inode %a 八进制权限 %A 符号权限 %U %u 属主 %G %g 属组 %y 可读 mtime %Y 秒级 mtime |
| 权限说明 | 读取元数据需要目录的执行权限;chown、chmod 等修改操作需要 root 或属主 |
典型使用场景
- 核对发布是否生效:比较 jar、静态文件的 mtime 与 inode,确认真的被替换而不是另存了同名新文件
- 排查 inode 耗尽:确认文件 inode 号,并配合 df -i 看文件系统的 inode 总量
- 安全核查:chmod 或 chown 之后 ctime 会变,靠 ctime 发现权限被篡改
- 脚本取数:stat -c 取大小或时间戳,比解析 ls -l 的文本稳定得多
- 确认链接关系:不加 -L 看到的是符号链接自身的元数据,加 -L 才是目标文件
常用示例
常用示例
stat /etc/passwd # 完整元数据
stat -c '%n %s %i %a %U:%G' /var/log/*.log # 脚本友好:名 大小 inode 权限 属主
stat -f /data # 文件系统的块与 inode 总量
stat -c '%n mtime=%y ctime=%z' app.jar # 分别看内容时间与元数据时间
stat -L /usr/bin/awk # 跟随符号链接,看目标文件
stat -c '%h %n' /etc/passwd # 硬链接数,超过 1 说明有多处引用输出项逐行读法
| 字段 | 含义 | 正常与异常 |
|---|---|---|
| Size | 文件字节大小 | 对目录而言只是目录项占用,不代表内容总量 |
| Blocks 与 IO Block | 占用 512 字节块数 / 文件系统块大小 | Blocks 明显小于 Size 说明是稀疏文件 |
| Inode | inode 号 | 跨设备比较无意义;文件被替换后 inode 通常改变 |
| Links | 硬链接数 | 目录至少为 2,普通文件大于 1 说明被多处引用 |
| Access | 八进制与符号两种权限表示 | 与预期不符时优先怀疑 umask 或误操作 chmod |
| Access / Modify / Change | 访问时间 / 内容修改时间 / 元数据变更时间 | ctime 随 chmod、chown、改名变化,它不是创建时间 |
| Birth | 创建时间 | btrfs、xfs 等支持,ext4 上通常显示为 - |
三个时间戳要区分:mtime 只在文件内容变化时更新,ctime 在任何元数据变化(权限、属主、链接数、重命名)时更新,atime 在读取时更新。取证判断「文件何时被改」只看 mtime 会漏掉权限篡改,只看 ctime 又会把 chmod 误当成内容修改。
脚本里取元数据优先用 stat -c,不要 awk 解析 ls -l:ls 的列会随选项、别名与本地化变化,而 stat 的格式符是稳定的接口。