%f 输出文件 st_mode 的十六进制原始值(无 0x 前缀),高 4 位表文件类型,低 12 位按 3 位一组编码 SUID/SGID/Sticky 及 owner/group/others 的 rwx 权限位。

stat -C "%f" 显示的是文件权限的**十六进制数值表示(不含前缀 0x)**,它直接对应 Linux 内核中 struct stat.st_mode 字段的低 16 位(实际常用低 12 位),即“mode bits”的原始整数值。这不是“物理权限位”的独立概念,而是内核存储权限、文件类型等信息的统一编码方式。
理解 %f 输出的含义
%f 输出的是 st_mode 的十进制值转为**小写十六进制(无 0x 前缀)**。例如:
-
-rw-r--r--→ 十进制33188→ 十六进制81a4(stat -C "%f" file输出81a4) -
drwxr-xr-x→ 十进制16877→ 十六进制41ed
这个十六进制数的每一位都承载语义:高 4 位(如 8xxx 中的 8)表示文件类型,低 12 位(如 xxx4)按 3 位一组分别表示 SUID/SGID/Sticky、owner、group、others 的 rwx 权限位。
拆解十六进制 mode bits 的实际步骤
以 81a4 为例(普通文件,-rw-r--r--):
- 转为二进制:
81a4₁₆ =1000 0001 1010 0100₂(共 16 位) - 按标准划分(从高位到低位):
- bit 15–12(类型):
1000₂ =8→ 普通文件(S_IFREG) - bit 11–9(特殊位):
000₂ → 无 SUID/SGID/Sticky - bit 8–6(owner):
110₂ = 6 →rw- - bit 5–3(group):
101₂ = 5 →r-x - bit 2–0(others):
000₂ = 0 →---?不对!实际是100₂ = 4 →r--(注意:最低三位是 bit 2,1,0,对应100)
- bit 15–12(类型):
- 更可靠方式:用
printf "%04x\n" $(stat -c "%a" file)获取八进制权限(如644),再转为二进制补零对齐,或直接查 Linux 内核头文件<asm-generic/stat.h>中的宏定义(如S_IRUSR,S_IWGRP)
结合其他 stat 字段验证权限位
单看 %f 不够直观,建议组合使用:
-
stat -c "Mode (hex): %f | Octal: %a | Full: %A" file→ 同时显示十六进制原始值、八进制权限、符号化权限串 -
stat -c "%f %F" file→ 对照文件类型(%F)确认高 4 位是否匹配(如regular file对应8xxx) - 用 C 或 Python 调用
stat()系统调用,打印st_mode并逐位掩码解析(如st_mode & S_IRUSR)
注意事项
%f 是 raw mode 值的十六进制字符串表示,不是“物理地址”或“磁盘扇区权限”。Linux 权限控制发生在 VFS 层,mode bits 存于 inode 内存结构及 ext4/xfs 等文件系统的磁盘 inode 中,但用户态无法也不需直接访问“物理位地址”。
真正需要分析内核级权限逻辑时,应查阅内核源码中 inode_permission() 和相关安全模块(如 SELinux)的钩子实现,而非仅依赖 stat 输出。


















