stat是唯一能直接读取inode元数据、一次性获取真实文件状态的命令,其权限、时间戳、inode号、硬链接数等字段均原样来自磁盘,不推算、不缓存;而ls -l仅提供残缺摘要,缺失inode号、Access/Change时间、八进制权限、设备号等关键信息。

stat 是唯一能直接读取 inode 元数据、一次性拿到真实文件状态的命令。它不是 ls -l 的增强版,而是底层事实来源——权限、时间戳、inode 号、硬链接数等字段都原样来自磁盘,不推算、不缓存、不省略。
为什么不用 ls -l 查文件状态?
ls -l 输出的是“人眼友好但信息残缺”的摘要:
• 它不显示 inode 编号,无法判断是否为硬链接或已删未释放文件
• 时间字段只默认显示 Modify(即 mtime),Access 和 Change 时间被隐藏
• 权限只给符号形式(如 -rw-r--r--),没有八进制值(644),脚本里不好解析
• 不体现设备号(Device)、块分配(Blocks)、IO 块大小(IO Block)等关键存储上下文
stat 的核心参数怎么选?
日常排查优先用 -c 定制输出,避免冗长默认格式干扰判断:
• 查权限归属: stat -c "%n %a %U:%G" /path/to/file
• 查 inode 与链接数(识别已删日志): stat -c "%i %h %s" /var/log/app.log
• 批量查配置文件权限: stat -c "%n %a %A" /etc/*.conf 2>/dev/null
• 跟软链到真实目标:加 -L,否则看到的是链接文件自身属性,不是它指向的内容
• 看文件系统级限制(比如报 “Permission denied” 却权限正常):用 stat -f / 检查 Inode 是否耗尽
三个时间戳到底在反映什么操作?
别再靠猜:
• Access:最后一次读取内容(cat、grep),但受挂载选项影响(noatime 下可能永远不变)
• Modify:最后一次改内容(echo >>、vim :w),最接近“文件是否被更新”的直觉
• Change:最后一次改元数据(chmod、chown、mv 重命名),比 Modify 更敏感,≠内容变更
• 注意:Birth(创建时间)在 ext4 上不可靠,多数发行版不支持,别依赖它
Linux 安全审计工具,检查 SSH 配置、开放/监听端口、防火墙规则(ufw/iptables/nftables)、失败登录尝试、sudoers 权限...
容易被忽略的底层细节
文件属性不只是权限和时间:
• Links 值为 0 表示文件已被 rm 删除,但仍有进程打开它(常见于未重启的守护进程日志)
• Device 字段配合 Inode 才能唯一定位物理位置,跨设备 mv 失败时要查这个
• SELinux 上下文(Context 字段)在强制访问控制启用时直接影响能否读写,ls -l 完全不显示它
• st_blocks 值小于 st_size / 512?说明文件有空洞(sparse file),实际占磁盘空间比看起来小










