这是"操作系统系列教程"的第四十八篇。上一篇我们讲了 RAID,知道了如何通过硬件级别的阵列保护数据不丢失。但这还不够,因为最坚固的堡垒往往是从内部被攻破的。如果服务器上的任何一个普通用户都能随便修改系统配置、查看别人的隐私文件,那系统依然毫无安全性可言。为了解决这个问题,操作系统引入了文件权限 机制。在 Linux 中,你经常看到
755、644这样的数字,它们到底是什么意思?rwx究竟代表了什么权力?这篇文章,我们就来把 Linux 的权限体系彻底扒开。
一次让人抓狂的 Permission denied
先来想象一个场景。你刚刚入职一家互联网公司,拿到了一台 Linux 测试服务器。你想在 /etc 目录下新建一个配置文件,熟练地敲下命令:
bash
$ touch /etc/my_config.conf
touch: cannot touch '/etc/my_config.conf': Permission denied
系统无情地拒绝了你。你不服气,又想看看服务器上其他同事写的代码,敲下:
bash
$ cd /home/zhangsan/project
bash: cd: /home/zhangsan/project: Permission denied
又是拒绝!
你可能会想:"我明明有这台服务器的账号密码,为什么这也不行,那也不行?"
这就涉及到了 Linux 系统设计的核心理念之一:多用户隔离与最小权限原则。在 Linux 看来,没有绝对的自由。每一个文件、每一个目录,都有其严密的"门禁系统"。谁有资格看?谁有资格改?谁有资格执行?一切都要凭"权限"说话。
很多人用了很多年 Linux,对权限的理解依然停留在"报错了就 chmod 777"的粗暴层面。这不仅极其危险,还会给自己埋下致命的安全隐患。
这篇文章,我们就来把"文件权限"扒个底朝天,从 UGO 模型讲起,深度剖析 rwx 的底层含义,解开数字权限的二进制密码,并带你领略特殊权限(SUID、SGID、粘滞位)的奇妙世界。
说明:本文涉及 Linux 权限模型、UGO、chmod、umask、ACL 等核心概念。初学者如果遇到暂时看不懂的术语,可以先跳过细节,重点理解"权限就是规定谁能对什么文件做什么操作"这一核心思想。
一、Linux 权限体系的基石:UGO 模型
在 Windows 系统中,权限控制往往非常复杂,甚至与具体的应用场景绑定。而 Linux 的权限控制极其简洁且优雅,它基于一个被称为 UGO 模型(User, Group, Others)的设计。
1.1 什么是 UGO?
在 Linux 中,每一个文件(哪怕是目录、设备、管道)都有三个"身份归属":
- User(所有者 / 属主) :文件的创建者,或者被指定的人。简称
u。 - Group(所属组 / 属组) :文件属于哪一个团队或用户组。简称
g。 - Others(其他人) :既不是所有者,也不在所属组里的其他所有用户。简称
o。
当你试图访问一个文件时,Linux 内核会按照 U -> G -> O 的顺序为你"验明正身":
- 如果你是文件的所有者,就按 U 的权限来管你;
- 如果你不是所有者,但在文件的所属组里,就按 G 的权限管你;
- 如果你既不是所有者也不在组里,那你就是 Others,按 O 的权限管你。
核心法则:内核一旦匹配到你的身份,就会立刻适用该身份的权限,绝不会向后兼容。
举个例子:如果文件所有者拥有读写权限(rw-),而其他人只有读权限(r--)。当你作为所有者去读这个文件时,系统判定你是 U,给你 rw-。尽管 O 也有 r--,但系统不会因为你同时也是 O,就给你合并权限。
1.2 实战:如何查看权限?
我们在 Linux 终端中输入 ls -l,会看到长长的一串字符:
text
-rwxr-xr-- 1 zhangsan dev_team 1024 Oct 10 10:00 my_script.sh
这行输出包含了丰富的信息,我们把它拆解开来:
- 第 1 个字符
-:代表文件类型(-是普通文件,d是目录,l是软链接)。 - 第 2-10 个字符
rwxr-xr--:这就是核心的权限位。 1:硬链接数。zhangsan:User(所有者)。dev_team:Group(所属组)。1024:文件大小(字节)。Oct 10 10:00:最后修改时间。my_script.sh:文件名。
1.3 权限位的三段论
那 9 个字符 rwxr-xr--,其实是整齐的三段论,每三个字符为一组:
rwx:所有者的权限(User)r-x:所属组的权限(Group)r--:其他人的权限(Others)

图 1:UGO 权限模型三段论。 9 个字符完美对应了三种身份。
二、穿透表象:rwx 到底代表什么?
很多初学者以为 rwx 就是"读、写、执行"。这句话对,但只对了一半。在 Linux 中,rwx 作用于普通文件和作用于目录时,含义是截然不同的! 这是面试和实际运维中最容易踩坑的地方。
2.1 针对"普通文件"的 rwx
对于文件来说,权限就是限制你对文件内容能做什么操作:
- r (Read,读权限) :允许你使用
cat、less、tail等命令查看文件的内容。 - w (Write,写权限) :允许你使用
echo、vim等命令修改、追加、清空文件的内容。注意:拥有 w 权限不代表你能删除这个文件! - x (Execute,执行权限) :允许你把这个文件当做程序或脚本运行(如
./my_script.sh)。如果一个脚本文件拥有rw-却没有x,你只能用bash my_script.sh来强行解释它,但无法直接用./运行。
2.2 针对"目录"的 rwx(重灾区)
如果你把一个目录(文件夹)当做普通文件来理解,你就彻底错了。目录的 rwx 限制的是你对"目录内部结构"的操作:
- r (Read,读权限) :允许你使用
ls列出目录内的文件名和子目录。如果没有r权限,你无法查看该目录下有哪些文件。 - w (Write,写权限) :允许你在该目录内新建、删除、重命名 文件或子目录。
- 极其重要 :哪怕一个文件的权限是
000(任何人都不能动它),只要它所在的目录有w权限,你就能用rm把它强制删掉!因为删除文件修改的是目录的数据块(目录项),而不是修改文件本身。
- 极其重要 :哪怕一个文件的权限是
- x (Execute,执行/进入权限) :允许你使用
cd命令进入该目录,也允许你访问该目录内文件的 inode(比如读取文件内容)。如果没有x权限,哪怕你有r权限,你也只能看到文件名,无法查看文件的详细信息(如大小、时间),也无法进入该目录。
一句话总结目录权限:
- 只有
r:能看不能进(像隔着玻璃看仓库)。 - 只有
x:能进不能看(像进了仓库但没带手电筒,什么都看不见)。 rx:能进也能看。rwx:想干嘛就干嘛。
#mermaid-svg-FfCvB6nUbr4aq4tw{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-FfCvB6nUbr4aq4tw .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-FfCvB6nUbr4aq4tw .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-FfCvB6nUbr4aq4tw .error-icon{fill:#552222;}#mermaid-svg-FfCvB6nUbr4aq4tw .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-FfCvB6nUbr4aq4tw .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-FfCvB6nUbr4aq4tw .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-FfCvB6nUbr4aq4tw .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-FfCvB6nUbr4aq4tw .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-FfCvB6nUbr4aq4tw .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-FfCvB6nUbr4aq4tw .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-FfCvB6nUbr4aq4tw .marker{fill:#333333;stroke:#333333;}#mermaid-svg-FfCvB6nUbr4aq4tw .marker.cross{stroke:#333333;}#mermaid-svg-FfCvB6nUbr4aq4tw svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-FfCvB6nUbr4aq4tw p{margin:0;}#mermaid-svg-FfCvB6nUbr4aq4tw .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-FfCvB6nUbr4aq4tw .cluster-label text{fill:#333;}#mermaid-svg-FfCvB6nUbr4aq4tw .cluster-label span{color:#333;}#mermaid-svg-FfCvB6nUbr4aq4tw .cluster-label span p{background-color:transparent;}#mermaid-svg-FfCvB6nUbr4aq4tw .label text,#mermaid-svg-FfCvB6nUbr4aq4tw span{fill:#333;color:#333;}#mermaid-svg-FfCvB6nUbr4aq4tw .node rect,#mermaid-svg-FfCvB6nUbr4aq4tw .node circle,#mermaid-svg-FfCvB6nUbr4aq4tw .node ellipse,#mermaid-svg-FfCvB6nUbr4aq4tw .node polygon,#mermaid-svg-FfCvB6nUbr4aq4tw .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-FfCvB6nUbr4aq4tw .rough-node .label text,#mermaid-svg-FfCvB6nUbr4aq4tw .node .label text,#mermaid-svg-FfCvB6nUbr4aq4tw .image-shape .label,#mermaid-svg-FfCvB6nUbr4aq4tw .icon-shape .label{text-anchor:middle;}#mermaid-svg-FfCvB6nUbr4aq4tw .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-FfCvB6nUbr4aq4tw .rough-node .label,#mermaid-svg-FfCvB6nUbr4aq4tw .node .label,#mermaid-svg-FfCvB6nUbr4aq4tw .image-shape .label,#mermaid-svg-FfCvB6nUbr4aq4tw .icon-shape .label{text-align:center;}#mermaid-svg-FfCvB6nUbr4aq4tw .node.clickable{cursor:pointer;}#mermaid-svg-FfCvB6nUbr4aq4tw .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-FfCvB6nUbr4aq4tw .arrowheadPath{fill:#333333;}#mermaid-svg-FfCvB6nUbr4aq4tw .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-FfCvB6nUbr4aq4tw .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-FfCvB6nUbr4aq4tw .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-FfCvB6nUbr4aq4tw .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-FfCvB6nUbr4aq4tw .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-FfCvB6nUbr4aq4tw .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-FfCvB6nUbr4aq4tw .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-FfCvB6nUbr4aq4tw .cluster text{fill:#333;}#mermaid-svg-FfCvB6nUbr4aq4tw .cluster span{color:#333;}#mermaid-svg-FfCvB6nUbr4aq4tw div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-FfCvB6nUbr4aq4tw .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-FfCvB6nUbr4aq4tw rect.text{fill:none;stroke-width:0;}#mermaid-svg-FfCvB6nUbr4aq4tw .icon-shape,#mermaid-svg-FfCvB6nUbr4aq4tw .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-FfCvB6nUbr4aq4tw .icon-shape p,#mermaid-svg-FfCvB6nUbr4aq4tw .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-FfCvB6nUbr4aq4tw .icon-shape .label rect,#mermaid-svg-FfCvB6nUbr4aq4tw .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-FfCvB6nUbr4aq4tw .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-FfCvB6nUbr4aq4tw .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-FfCvB6nUbr4aq4tw :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 目录的 rwx
r: 列出文件列表 (ls)
w: 新建/删除/重命名文件 (touch/rm)
x: 进入目录 (cd)
普通文件的 rwx
r: 查看内容 (cat)
w: 修改内容 (vim)
x: 运行程序 (./script)
图 2:文件与目录的权限差异。 同样是
w,对文件是改内容,对目录是删文件。
三、数字权限的由来:二进制与八进制的魔法
面对 rwxr-xr-- 这么长一串字符,每次修改都要敲这么多字母,运维人员觉得太麻烦了。于是,Linux 引入了数字权限(八进制表示法)。
3.1 权重的赋予
rwx 分别被赋予了固定的数值权重。这是因为计算机底层是二进制,用二进制位表示权限再合适不过了:
- r (读) = 4 (二进制
100) - w (写) = 2 (二进制
010) - x (执行) = 1 (二进制
001) - - (无权限) = 0 (二进制
000)
3.2 加法运算
有了权重,我们就可以把每一组权限转换为数字,只要把对应权限的数字加起来就行了。
例如 rwx = 4 + 2 + 1 = 7 。
例如 r-x = 4 + 0 + 1 = 5 。
例如 r-- = 4 + 0 + 0 = 4 。
例如 --- = 0 + 0 + 0 = 0。
3.3 破解 755 与 644 的终极密码
现在,你回头看看那些熟悉的数字:
-
755(代表rwxr-xr-x):- U (所有者):
7=rwx(读、写、执行全都有)。 - G (所属组):
5=r-x(能读、能执行,不能改)。 - O (其他人):
5=r-x(能读、能执行,不能改)。 - 场景 :极其适合目录 和可执行程序 。因为目录必须要有
x权限才能cd进去,而普通用户不需要修改它,所以不能给w。
- U (所有者):
-
644(代表rw-r--r--):- U (所有者):
6=rw-(读、写)。 - G (所属组):
4=r--(只读)。 - O (其他人):
4=r--(只读)。 - 场景 :极其适合普通文件。比如你的网页代码、文本配置。你可以改,别人只能看。
- U (所有者):
-
600(代表rw-------):- 只有所有者能读能写,其他人连看的资格都没有。
- 场景 :最典型的应用就是 SSH 的私钥文件(
id_rsa)。如果你的私钥权限是 644,SSH 会直接拒绝工作,因为它怕你的私钥泄露。
-
777(代表rwxrwxrwx):- 所有人想干嘛就干嘛。
- 场景 :除了在本地回收站或极其特殊的测试环境,绝对不要用!这是黑客提权和勒索病毒的最爱。

图 3:数字权限的八进制转换逻辑。
四、进阶必修:Linux 的特殊权限 (SUID / SGID / Sticky)
除了基础的 rwx,Linux 还有三位隐藏的"特殊权限",它们挂在权限位的最前面,用 s 或 t 表示。它们极大地改变了程序的运行逻辑,是 Linux 安全攻防的核心。
4.1 SUID(Set User ID,数字 4)
作用 :当一个可执行文件被设置了 SUID 权限,普通用户在执行该程序时,会临时获得该文件所有者(通常是 root)的权限。
经典案例:/usr/bin/passwd
普通用户都可以通过 passwd 命令修改自己的密码。但密码存放在 /etc/shadow 文件中,这个文件只有 root 才有写权限。为什么普通用户能修改?
用 ls -l /usr/bin/passwd 看看:
text
-rwsr-xr-x. 1 root root 27832 Jun 10 2021 /usr/bin/passwd
注意看所有者的 x 位变成了 s。这就意味着,当你运行 passwd 时,你的身份瞬间"灵魂附体"成了 root,从而拥有权限去修改 /etc/shadow。
安全警告:如果一个黑客在服务器上找到了一个带有 SUID 权限,且能被普通用户篡改的自定义程序,黑客就能利用它获取 root 权限(俗称 SUID 提权)。
4.2 SGID(Set Group ID,数字 2)
作用:
- 针对文件:执行该文件时,临时获得文件所属组的权限。
- 针对目录(最常用) :在一个设置了 SGID 的目录下,用户创建的新文件或新目录,其所属组会自动继承该目录的所属组。
场景 :公司有一个 project 目录,组是 dev。张三(在 dev 组)创建了文件 a.txt,如果没有 SGID,a.txt 的组默认是张三的个人组;如果 project 目录设置了 SGID,a.txt 的组就会自动变成 dev,这样团队里其他人就都能访问这个文件了。
4.3 Sticky Bit(粘滞位,数字 1)
作用 :针对目录。如果一个目录设置了粘滞位,只有文件的所有者、目录的所有者或 root 用户,才能删除或重命名该目录内的文件 。其他普通用户即使对该目录有 w 权限,也无法删除别人的文件。
经典案例:/tmp 目录
Linux 的 /tmp 是所有人共享的临时目录。如果不设置粘滞位,张三就能把李四刚写的代码删除。而设置了粘滞位后:
text
drwxrwxrwt. 10 root root 4096 Oct 10 10:00 /tmp
注意最后的 t。现在张三只能在 /tmp 里删自己的文件,动不了别人的文件。
4.4 特殊权限的数字表示法
因为 SUID=4,SGID=2,Sticky=1。
你有时会看到 4755 或 1777 这样的四位数字:
4755=SUID+rwxr-xr-x1777=Sticky+rwxrwxrwx

图 4:Linux 三大特殊权限总结。 它们是系统底层机制的基石。
五、权限修改利器:chmod、chown 与 umask
光懂理论不行,得会实操。更改权限主要靠这三个命令。
5.1 chmod(Change Mode)
用于修改文件的 rwx 权限。有两种写法:
1. 字母法(直观,适合局部微调)
u(User),g(Group),o(Others),a(All)+(加权限),-(减权限),=(赋予唯一权限)
bash
# 给所有者增加执行权限
chmod u+x script.sh
# 收回其他人的写权限
chmod o-w file.txt
2. 数字法(干练,适合批量设置)
bash
# 设置为 755
chmod 755 script.sh
# 递归把目录及其内部所有文件设为 644
chmod -R 644 /my_dir
5.2 chown 与 chgrp(属主与属组修改)
chown:Change Owner,修改所有者。chgrp:Change Group,修改所属组。
bash
# 把文件所有者改为 tom,所属组改为 dev
chown tom:dev file.txt
# 递归修改目录的所有者
chown -R tom /home/tom/
5.3 umask(遮罩码:默认权限的"减法")
为什么你新建一个文件,默认权限是 644?新建一个目录,默认权限是 755?这是因为 umask 的存在。
- 默认基础权限 :文件默认是
666(不给执行权限),目录默认是777。 - umask 值 :默认通常是
022。 - 计算规则:最终权限 = 基础权限 - umask(按位做交集运算)。
对于文件:666 - 022 = 644。
对于目录:777 - 022 = 755。
你可以用 umask 命令查看或修改它。如果你执行 umask 077,那你新建的文件权限就会变成 600(只有自己能看),极其安全。
六、打破 UGO 局限:ACL 访问控制列表
UGO 模型虽然经典,但有时候不够用。比如,张三有一个文件,他属于 dev 组。但他只想让 ops 组里的李四能看,其他人都不能看。这就打破了"三组论"的框架。
怎么办?我们需要引入 ACL(Access Control List,访问控制列表) 。ACL 允许你在传统的 UGO 之外,针对特定的单个用户 或特定的用户组单独赋予权限。
bash
# 查看文件的 ACL 权限
getfacl file.txt
# 给特定用户 (李四) 赋予读写权限
setfacl -m u:lisi:rw file.txt
当文件有 ACL 权限时,ls -l 的结果中的权限位后面会多出一个 + 号,如 -rw-rw-r--+。
七、常见误区与安全避坑指南
| 误区 | 真相 |
|---|---|
| "只要我是文件所有者,我就能删除它" | 错。能否删除文件,取决于文件所在目录 是否有 w 权限。如果目录不让你写,哪怕你是文件爹,你也删不掉。 |
| "给个 777 就能解决所有报错" | 极其危险!777 意味着任何黑客或恶意程序都能植入脚本、篡改你的业务。必须遵循最小权限原则。 |
| "目录有 r 就能 cd 进去" | 错。cd 进入目录需要的是 x 权限。只有 r 的话,你只能 ls 看到名字,但进不去。 |
| "root 权限会被权限位限制" | root 是超级管理员,拥有至高无上的权力,即使文件的权限是 000,root 也能强行读写(除了某些 immutable 不可变属性)。 |
| "chmod -R 777 /" 会提速" | 这等于把系统的底裤脱了,系统会直接半身不遂或瞬间被黑。 |