从 chmod 755 说起:Unix 文件权限到底是怎么算的?

刚学 Linux 的时候,很多人都背过「755 是 rwxr-xr-x,644 是 rw-r--r--」。

但说真的,你有没有想过------为什么读是 4,写是 2,执行是 1?为什么 7 就代表 rwx?这三个数字到底是怎么拼出来的?

这篇文章不讲 chmod 命令怎么用(那个 man 手册写得更清楚),而是聊清楚权限数字背后的位运算逻辑,以及怎么用代码实现一个权限计算器。

权限的二进制本质

Unix 的权限系统其实就三组、每组三位,对应三个角色:

每组三位分别表示 r(读)、w(写)、x(执行),用二进制表示就是:

bash 复制代码
rwx  →  111  →  7
rw-  →  110  →  6
r--  →  100  →  4
---  →  000  →  0

所以 755 的完整含义是:

bash 复制代码
Owner:  rwx  →  7  →  111
Group:  r-x  →  5  →  101
Others: r-x  →  5  →  101

本质就是把三组三位二进制数(每组 0-7),拼成一个三位八进制数。所以叫 chmod,change file mode bits,一个比特都不浪费。

面试最爱问的 umask

理解了二进制本质,umask 就很好懂了。umask 表示要屏蔽哪些权限位:

bash 复制代码
# 当前 umask
$ umask
0022

# 新文件默认权限 = 666 & (~022) = 644
# 新目录默认权限 = 777 & (~022) = 755

因为文件默认不应该有执行权限(除非显式指定),所以文件基数是 666,目录是 777。umask = 0022 就是把 group 和 others 的写权限去掉。

对应的位运算:

bash 复制代码
function applyUmask(base: number, umask: number) {
  return base & (~umask)
}
// 文件: 0o666 & (~0o022) = 0o644
// 目录: 0o777 & (~0o022) = 0o755

权限计算的核心实现

回到 chmod 计算器的实现。把八进制转成权限矩阵,本质就是做三次位测试:

bash 复制代码
type Permission = 'r' | 'w' | 'x'
type Scope = 'owner' | 'group' | 'others'

function octalToPerms(octal: string) {
  const digits = octal.split('').map(Number)
  // 三个 digit 分别对应 owner/group/others
  // 每个 digit 的二进制位对应 r/w/x
  const scopes = ['owner', 'group', 'others']
  return scopes.map((scope, i) => {
    const d = digits[i]
    return {
      r: (d & 4) !== 0,  // 检查第 3 位
      w: (d & 2) !== 0,  // 检查第 2 位
      x: (d & 1) !== 0,  // 检查第 1 位
    }
  })
}

权限转回八进制就更直接了,就是加权求和:

bash 复制代码
function permsToOctal(perms) {
  let v = 0
  if (perms.r) v += 4
  if (perms.w) v += 2
  if (perms.x) v += 1
  return v
}

这其实就是教科书里的「按权展开」------每个 bit 的权重分别为 4、2、1。

两个经常被忽略的特殊权限

setuid(4000)和 setgid(2000)

八进制权限其实是四位,最高位控制特殊行为:

  • 4 = setuid:以文件所有者的身份执行(典型的如 /usr/bin/passwd 需要 root 权限改密码)
  • 2 = setgid:以文件所属组的身份执行
  • 1 = sticky bit:限制目录中文件的删除权限(/tmp 目录就是典型的例子)
bash 复制代码
# 给程序设置 setuid
chmod 4755 some-program

# 查看效果
$ ls -l some-program
-rwsr-xr-x  1 root  staff  some-program  # s 代替了 owner 的 x

注意这里的 4(setuid)和权限计算中的 4(read)含义完全不同------一个是控制位,一个是数据位。因为 setuid 只对 owner 的 execute 位有意义,如果 owner 没有 x 权限,setuid 会变成大写的 S(表示无效)。

sticky bit(1000)

bash 复制代码
chmod 1777 /tmp
# drwxrwxrwt 中的 t 表示 sticky bit 已设置

设置了 sticky bit 的目录,用户只能删除自己的文件------这在多用户系统中防止乱删文件。

记忆技巧

三个特殊权限位的数值 4/2/1 和普通权限位完全一样,唯一的区别是作用范围不同:

bash 复制代码
特殊位: SUID(4) | SGID(2) | Sticky(1)
普通位: Read(4) | Write(2) | Execute(1)

如果你记得 4+2+1=7 是 rwx,那 4+2+1=7 就是所有特殊权限同时开启------结构完全一致。

最终效果

基于上面的逻辑,做了一个可视化的权限计算器:chmod 计算器

功能包括:

  • 通过勾选任意修改权限
  • 实时显示八进制和符号表示
  • 内置 755/644/600/700 等预设
  • 直接复制 chmod 命令

权限本身不复杂,本质就是三位二进制数,但要做好工具还是需要把位运算逻辑处理清楚。希望对你理解 chmod 有帮助。


相关工具:Linux 命令速查 | HTTP 状态码 | IP 计算器

相关推荐
Strugglingler1 小时前
【systemctl 学习总结】
linux·systemd·systemctl·journalctl·unit file
嵌入式×边缘AI:打怪升级日志3 小时前
100ASK-T113 Pro 开发板 Bootloader 完全开发指南
linux·ubuntu·bootloader
charlie1145141914 小时前
Linux 字符设备驱动:cdev、设备号与设备模型
linux·开发语言·驱动开发·c
handler014 小时前
Linux 内核剖析:进程优先级、上下文切换与 O(1) 调度算法
linux·运维·c语言·开发语言·c++·笔记·算法
zhouwy1134 小时前
Linux进程与线程编程详解
linux·c++
我星期八休息4 小时前
IT疑难杂症诊疗室:AI时代工程师Superpowers进化论
linux·开发语言·数据结构·人工智能·python·散列表
切糕师学AI5 小时前
深入解析 Zsh 与 Oh-My-Zsh:打造高效现代化终端
linux·终端·zsh
切糕师学AI6 小时前
Ubuntu 下 Git 完全使用指南
linux·git·ubuntu
浪客灿心6 小时前
Linux网络传输层协议
linux·运维·网络