Linux 权限管理:从「Permission Denied」到「畅行无阻」

如果你曾在终端里敲命令时被一句 Permission denied 怼回来过,这篇文章就是为你准备的。我们将从「为什么要有权限」开始,把用户切换、rwx、chmod 八进制、umask 掩码、粘滞位这些看似零散的知识点串成一条完整的逻辑链。


前置知识:为什么会有「权限」这种东西?

一个很现实的场景

Linux 是多用户操作系统 。一台服务器上可能同时有 root 管理员、后端开发、前端开发、运维实习生同时登录。如果实习生不小心 rm -rf /,那就出大事了。

权限的本质:决定谁(用户/角色)能对什么资源(文件/目录)做什么操作(读/写/执行)。

复制代码
权限 = 人(用户 + 角色) + 文件属性(rwx)
  • :你的账号身份是什么?root 还是普通用户?你在目标文件面前扮演什么"角色"?
  • 文件属性:目标文件身上挂了哪些权限标签(可读?可写?可执行?)

两种用户级别

用户类型 特点
root(超级用户) 不受权限限制,可以做任何事。例如 root 切换到任何普通用户都不需要密码
普通用户 受权限约束,只能访问自己被授权的内容

🔑 root 的"特权体现"之一:su 切换到任何用户无需输入目标用户的密码,而普通用户 su 切换时必须输入目标密码。


第一部分:su 和 sudo ------ 切换身份的两种姿势

su(switch user)

复制代码
su            # 不跟用户名,默认切换到 root(因为系统 100% 存在 root)
su alice      # 切换到 alice 用户
su -          # 以"重新登录"的方式切换,自动跳转到目标用户的家目录
su - alice    # 组合用法

密码规则:

切换方向 需要谁的密码?
普通用户 → root 输入 root 密码
root → 普通用户 不需要密码(特权)
普通用户 A → 普通用户 B 输入 B 的密码

sudo(super user do)

su 的问题是什么?你告诉了别人 root 密码,他就能为所欲为。sudo 解决了这个问题。

复制代码
sudo vim /etc/nginx/nginx.conf    # 临时提权执行单条命令

sudo 的逻辑:

  1. 你输入自己的密码(不是 root 密码!)
  2. 系统查 /etc/sudoers 这个白名单文件,看你是不是被允许执行这条命令
  3. 白名单的编辑权限只在 root 手里,普通用户改不了

为什么 sudo 不设计成输入 root 密码?

如果输入的是 root 密码,那 sudo 就退化成了 su ------ 知道 root 密码的人还是可以为所欲为。sudo 的设计哲学是:短暂地放宽一个受信任用户的权限,而不是交出 root 的钥匙。白名单机制让 root 可以在不泄露自己密码的前提下,精准控制"谁可以做什么"。

su vs sudo 对比:

su sudo
需要谁的密码 目标用户的密码 自己的密码
权限范围 完全切换身份 单条命令临时提权
安全程度 知道 root 密码 = 拥有 root 白名单精准控制,root 密码不外泄
适用场景 管理员日常维护 给普通用户开放特定高权限操作

第二部分:文件权限的构成 ------ 三个角色 × 三种操作

ls -l 看一个文件的属性:

复制代码
-rw-r--r--  1  alice  dev   50  Jul 19 17:23  test.txt

拆解第一列的 -rw-r--r--

复制代码
-    rw-    r--    r--
│     │      │      │
│     │      │      └── other 权限(其它用户)
│     │      └───────── group 权限(所属组)
│     └──────────────── user 权限(拥有者)
└────────────────────── 文件类型(- = 普通文件,d = 目录,l = 链接)

三个角色

角色 缩写 说明 举例
拥有者 u(user) 文件的主人,一般是创建者 alice 创建的 test.txt,拥有者是 alice
所属组 g(group) 一个用户组,组内成员共享权限 dev 组的所有成员对 test.txt 拥有 g 权限
其它者 o(other) 既不是拥有者、也不属于所属组的所有人 路人甲

为什么要有所属组?

当你想对特定的一群人开放权限,而不是对所有人开放时,组就是最合适的管理单元。比如后端开发组能读写项目代码,但前端组只能读。

三种权限

权限 字母 对文件 对目录
可读 r 能查看文件内容(catmore 能列出目录内的文件名(ls
可写 w 能修改文件内容 能在目录内新增、删除、重命名文件
可执行 x 能运行该文件(可执行程序/脚本) 进入 该目录(cd),能访问目录内文件

🔴 关键认知 :同一个 r/w/x,对文件和目录的含义完全不同。比如目录的 w 权限决定的是你能不能在里面新建/删除文件,而不是修改目录本身的内容。


第三部分:chmod ------ 修改文件权限

⚠️ 只有文件的拥有者root 才能修改文件的权限。

方式一:符号法(直观,适合新手)

复制代码
chmod  角色  操作  权限  文件名
      │     │     │
      u     +     r
      g     -     w
      o     =     x
      a(all,全部)

示例:

复制代码
chmod u+w test.txt           # 给拥有者添加写权限
chmod g-r test.txt           # 去掉所属组的读权限
chmod o+x script.sh          # 给其它用户添加执行权限
chmod a+r shared.txt         # 给所有人添加读权限(等于不写角色,默认 a)
chmod u-rw,g+r test.txt      # 同时修改多个角色,用逗号隔开(逗号后不要加空格!)
chmod u=rwx,g=rx,o= test.txt # = 表示精确设置为指定权限(o= 表示 other 没有任何权限)

方式二:八进制数字法(更常用,高手必备)

每个权限对应一个数字:

复制代码
r(读)= 4
w(写)= 2
x(执行)= 1
-(无)= 0

例如:
rwx = 4+2+1 = 7
rw- = 4+2+0 = 6
r-x = 4+0+1 = 5
r-- = 4+0+0 = 4
-w- = 0+2+0 = 2
--x = 0+0+1 = 1
--- = 0+0+0 = 0

三个角色各用一个 0~7 的数字表示,组成三位数:

复制代码
chmod 755 script.sh     # rwx r-x r-x → 拥有者全权限,其他人只读+执行
chmod 644 data.txt      # rw- r-- r-- → 拥有者可读写,其他人只读
chmod 600 secret.txt    # rw- --- --- → 只有拥有者能读写(私密文件)
chmod 777 public.txt    # rwx rwx rwx → 所有人全权限(不安全!)

常见数字组合速查:

数字 含义 典型用途
755 rwx r-x r-x 可执行脚本、目录
644 rw- r-- r-- 普通文本文件
600 rw- --- --- 私钥、密码文件
700 rwx --- --- 个人脚本
777 rwx rwx rwx 临时共享(⚠️ 不推荐长期使用)

⚡ 权限匹配的"一次验证"原则

这是一个很容易踩坑的机制:

用户访问文件时,系统按照 u → g → o 的顺序匹配身份,只匹配一次。一旦身份确定,就只看该身份的权限,不会因为 g 权限更大而"降级"使用。

示例: alice 是 test.txt拥有者 ,同时也是其所属组 dev 的成员。

复制代码
-r---w-rw-  1  alice  dev  test.txt

alice 对此文件的权限是 r--(只有读),不是 rw-。为什么?因为系统先匹配到她是拥有者(u),就锁定用 u 的权限(r--),不会再去检查她作为组成员的 g 权限。

💡 一句话:权限验证是"一次匹配,立即生效",不是"取所有身份的最大权限"。


第四部分:chown 和 chgrp ------ 修改文件的拥有者和所属组

⚠️ 修改拥有者和所属组是 root 专属权限 。即使你是文件的拥有者,也不能把文件"送给"别人,只能用 sudo

复制代码
# chown:修改拥有者(change owner)
chown root test.txt              # 把拥有者改为 root
chown alice:dev test.txt         # 同时修改拥有者和所属组
chown :dev test.txt              # 只修改所属组(冒号前留空)

# chgrp:修改所属组(change group)
chgrp dev test.txt               # 把所属组改为 dev

实际演示:

复制代码
[root@server ~]# ll
-r-------- 1 whb whb 50 Jul 19 17:23 test.txt   # 拥有者 whb,所属组 whb

[root@server ~]# chown root test.txt
-r-------- 1 root whb 50 Jul 19 17:23 test.txt   # 拥有者 → root

[root@server ~]# chgrp root test.txt
-r-------- 1 root root 50 Jul 19 17:23 test.txt  # 所属组 → root

[root@server ~]# chown whb:whb test.txt
-r-------- 1 whb whb 50 Jul 19 17:23 test.txt    # 一键改回

第五部分:Linux 文件类型速览

ls -l 输出的第一个字符代表的不是权限,而是文件类型

首字符 类型 说明 举例
- 普通文件 源代码、文本、可执行程序、图片、库 hello.ca.out
d 目录 目录本质上也是文件,存储的是其内部文件的元数据列表 my_project/
l 符号链接 相当于 Windows 的快捷方式 /lib64 → usr/lib64
c 字符设备 按顺序 IO,以字符为单位,不支持随机读写 键盘、显示器
b 块设备 支持随机读写,以数据块为单位 硬盘、U 盘
p 管道文件 进程间通信
s 套接字 网络/本地进程间通信

第六部分:目录的 rwx ------ 一个容易搞错的地方

目录本身只是一个"登记表",存储的是内部文件的属性 (文件名、inode 号等),而不是文件的内容。理解了这一点,下面的规则就顺了。

进入一个目录需要什么权限?

权限 能否进入目录(cd) 能否 ls 查看文件名 能否在目录内新建/删除/重命名 能否访问目录内的文件
只有 r ❌ 进不去 ✅ 能 ls(但看不到详细信息) ❌(进都进不去)
只有 w ❌ 进不去 ❌(进不去,谈何操作)
只有 x ✅ 能进 ❌ 无法 ls ✅(知道文件名就能读内容)
r + x ✅ 能进 ✅ 能 ls
w + x ✅ 能进 ✅(知道文件名就行)
r + w + x ✅ 能进

🔑 记忆技巧

  • x 是"进门卡" ------ 没有 x,目录的门你都进不去
  • r 是"花名册" ------ 允许你查阅目录里有哪些文件(ls
  • w 是"增删改签" ------ 允许你在花名册上添加、划掉、改名(不影响文件内容本身)

一个反直觉的细节

如果目录的 w 权限被关闭,但文件的 w 权限保持打开:

复制代码
chmod 555 mydir/              # 目录:r-x r-x r-x(没有 w)
# 此时无法在 mydir/ 下新建、删除、重命名文件
# 但如果 mydir/ 下已有文件 hello.txt(rw-rw-rw-)...
vim mydir/hello.txt           # ✅ 可以修改文件内容!

目录的权限管不到文件内容 ------ 它只管"登记表"上的增删改。所以:

删除文件 ≠ 修改文件内容。删除是修改目录的"登记表"(目录的内容),修改是改文件的"正文"(文件的内容)。两者互不干涉。


第七部分:umask ------ 为什么新建文件的默认权限是那样?

新建一个文件/目录时,默认权限是怎么来的?

起始权限

文件类型 起始权限 原因
普通文件 666(rw-rw-rw-) 默认不需要执行权限,大部分文件是文本/数据
目录 777(rwx rwx rwx) 进入目录需要 x,所以默认给予

权限掩码 umask

但实际新建的文件并不会是 666/777。看看你自己系统:

复制代码
$ umask
0002

umask(权限掩码)的作用:凡是在掩码中出现的权限,都要在起始权限中去掉。

复制代码
最终权限 = 起始权限 & (~umask)     # 位运算:取反后按位与

⚠️ 这个"去掉"不是数学减法 ,而是位运算 。不要用 777 - 022 = 755 来理解,虽然结果碰巧相同,但原理完全不同。

实际计算

假设 umask = 022(最常见的值):

复制代码
普通文件:
  起始        666     rw- rw- rw-
  umask       022     --- -w- -w-    (掩码:要去掉组写和其他写)
  ~umask      755     rwx r-x r-x
  666 & 755 = 644     rw- r-- r--

目录:
  起始        777     rwx rwx rwx
  777 & 755 = 755     rwx r-x r-x

结论:

  • 新建普通文件 → rw- r-- r--(644):拥有者可读写,其他人只读 ✅
  • 新建目录 → rwx r-x r-x(755):拥有者全权限,其他人可读可进入 ✅

💡 umask 越大,默认权限越小 。例如 umask 077 会让新建文件只有拥有者能访问。

修改 umask

复制代码
umask              # 查看当前掩码值
umask 027          # 临时设置(重启后失效)

第八部分:粘滞位(Sticky Bit)------ 共享目录中的隔离墙

问题场景

假设有一个多人共享目录 /shared,权限为 rwx rwx rwx(777):

  • whb 创建了 whb_report.txt(属于 whb)
  • 另一个用户 maisui 进入 /shared,可以删除 whb_report.txt!😱

为什么?因为目录的 w 权限给了 other,允许"在目录内删除文件"。

矛盾点

复制代码
我需要 other 有 w 权限 → 这样才能在共享目录里创建文件
但我又不想 other 删我的文件 → w 权限允许删任何人的文件

怎么办?

粘滞位登场

复制代码
chmod o+t /shared       # 给目录的 other 加上粘滞位
# 或
chmod +t /shared        # 简写,默认加到 other 上

加上粘滞位后,目录的 other 权限位从 x 变为 t

复制代码
drwxrwxrwt  2  root  root  4096 Aug 3 18:00 shared/
#        ↑ 注意这个 t,说明粘滞位已生效

粘滞位的规则: 在设置了粘滞位的目录下 ---

谁能删除文件? 条件
root(超级用户) ✅ 永远可以
目录拥有者
文件拥有者
其他用户 ❌ 即使有 w 权限也不能删别人的文件

🎯 满足"既能让大家共享,又保护每个人创建的文件不被别人删除"。

典型应用

Linux 的 /tmp 目录默认就设置了粘滞位:

复制代码
$ ls -ld /tmp
drwxrwxrwt 20 root root 4096 Aug  3 18:00 /tmp/
#        ↑ 看到 t 了吧

第九部分:通配符 * ------ 批量操作的利器

跟权限搭配的常用姿势:

复制代码
ls *.c           # 列出所有 .c 结尾的文件
ls te*           # 列出所有 te 开头的文件
chmod 644 *.txt  # 批量修改所有 .txt 文件的权限
rm *.tmp         # 删除所有 .tmp 文件

📌 * 代表"任意字符,任意长度"。*.c = 所有以 .c 结尾的文件,te* = 所有以 te 开头的文件。


总结:一张图看清全部

权限位完整解读

复制代码
  -   rw-   r--   r--
  │    │     │     │
  │    │     │     └── other(o):4 = r--
  │    │     └──────── group(g):4 = r--
  │    └────────────── user(u):6 = rw-
  └─────────────────── 文件类型:- = 普通文件

数字表示:644

命令速查表

命令 作用 示例
su 切换用户 su - alice
sudo 单条命令提权 sudo vim /etc/hosts
chmod 符号法 修改权限(加减) chmod u+w test.txt
chmod 数字法 修改权限(数字) chmod 755 script.sh
chown 修改拥有者 chown alice:dev test.txt
chgrp 修改所属组 chgrp dev test.txt
umask 查看/设置权限掩码 umask 027
chmod +t 设置粘滞位 chmod +t /shared

关键认知集锦

  1. 权限只验证一次:u → g → o 顺序匹配,匹配到就停,不取最大值
  2. 目录的 rwx ≠ 文件的 rwx:目录的 w 管增删改名,文件的 w 管内容修改
  3. 删除文件与文件权限无关,与目录权限有关 :你能否删一个文件,取决于你对目录有没有 w 权限
  4. 最终权限 ≠ 起始权限 - umask :是位运算 起始权限 & (~umask)
  5. 粘滞位只对 other 生效chmod +tchmod o+t 是等价的
  6. chown/chgrp 只有 root 能做:文件的拥有者也不能把文件送人

📚 最好的学习方式 :开一个终端,用 touch a.txt 建个文件,然后把本文中的每条 chmodchownumask 命令都敲一遍,每次改完用 ls -l 看变化。权限这东西,敲 10 分钟就全记住了。


本文力求为初学者提供准确、全面、易理解的 Linux 权限知识体系。如有疏漏,欢迎指正。

相关推荐
BullSmall1 小时前
scanoss-engine 本地最简部署 & 扫描命令(Linux/Anolis OS)
linux·运维·服务器
bellus-2 小时前
Ubuntu 26.04 Miniforge3 安装与配置完整指南
linux·运维·ubuntu
用什么都重名3 小时前
Ubuntu 24.04 安装 NVIDIA 驱动:解决 “NVIDIA-SMI has failed“ 报错全记录
linux·运维·ubuntu
Industio_触觉智能3 小时前
瑞芯微ISP内核驱动深度解析|RKISP39从架构到Probe初始化全流程(上篇)
linux·嵌入式硬件·硬件架构·摄像头·isp·瑞芯微·rk3576
有续技术3 小时前
三菱 (Mitsubishi) 机床 设置查看 IP 地址
linux·服务器·网络
yagami_gagami4 小时前
第四届黄河流域公安院校电子物证个人赛服务器取证
linux·服务器·网络·mysql·安全·docker·llama
邪修king4 小时前
Re:Linux系统篇(七) 开发工具篇 Chapter3:Makefile 从入门到精通 —— 依赖关系、伪目标、栈式推导与自动化构建全解
linux·运维·服务器·vim
bosins4 小时前
Ubuntu 日常最常用的文件操作场景和对应指令
linux·服务器·ubuntu
风曦Kisaki4 小时前
Kubernetes(K8s)笔记Day07: StatefulSet 有状态控制器详解与使用案例
linux·docker·云原生·容器·kubernetes