lsattr 用于查看文件扩展属性,第5位为i表示不可修改,末两位e-表示extent存储;stat直接读取inode元数据验证真实权限和时间戳;lslocks检查进程级运行时锁,三者分别对应扩展属性、运行时锁和权限上下文三层排查。

用 lsattr 看扩展属性,但得先确认文件系统支持
文件是否被加了不可变锁(+i)、追加只读锁(+a)等,必须用 lsattr 查。输出里从左到右第 5 位是 i,就代表该文件已被设为不可修改;最后两位是 e-,说明用 extent 存储、没其他特殊标记;中间全是 - 就表示没设额外属性。
但注意:lsattr 在某些环境会报错或显示空白,比如:
- FAT32/NTFS 挂载卷不支持扩展属性,直接提示
Operation not supported - 容器内、NFS 或 CIFS 挂载点通常也不提供该能力
- 普通用户执行可能被拒绝,必须用
sudo lsattr
用 stat 验证真实权限和时间戳,避开 ls -l 的误导
ls -l 显示的权限只是符号化结果,不能反映 chattr 设置的隐藏锁。真正要看底层状态,得用 stat ——它直接读 inode 元数据,不推算、不缓存。
常用组合:
-
stat -c "%n %a %A %U:%G %x %y %z" /path/to/file:一次性看文件名、八进制权限、符号权限、所有者/组、Access/Modify/Change 时间 -
stat -c "%i %h" /path/to/file:查 inode 号和硬链接数,若%h为 0,说明文件已被删但进程仍占着句柄 -
stat -f /path/to/file:查所在文件系统是否启用ext4或xfs,只有这些才支持chattr +i
用 lslocks 查运行时文件锁(flock/POSIX),不是扩展属性
很多人混淆“文件被 chattr +i 锁住”和“被某个进程用 flock() 或 fcntl() 加了运行时锁”。前者是文件系统级强制保护,后者是进程协作式控制,lslocks 查的就是后者。
查具体文件是否被某进程锁住:
-
lslocks | grep "/path/to/file":快速过滤,看 TYPE 是 FLOCK 还是 POSIX,PID 和 MODE 列告诉你谁在读/写哪一段 -
lslocks --output PID,TYPE,MODE,START,END,PATH | grep "filename":定制输出,避免字段截断 - 如果没结果,不代表没锁——可能是锁在子进程、或用了非标准方式(如
open(O_EXCL)),得配合lsof或fuser
综合判断:三个命令各管一块,缺一不可
一个文件“打不开/删不掉/改不了”,原因可能横跨三层:
- 扩展属性层:
lsattr是否显示i或a?有则需chattr -i解锁 - 运行时锁层:
lslocks或lsof是否有活跃持有者?有则要 kill 对应 PID - 权限与上下文层:
stat显示的 UID/GID 是否匹配当前用户?SELinux/AppArmor 是否拦截?
最容易漏的是第一层:明明 chmod 777 了还写失败,却不查 lsattr,卡半天才发现是 +i 在起作用。


















