Linux基础指令(三):权限系统详解

本文是 Linux 基础指令系列的第三篇,聚焦 Linux 权限系统——从本质理解到实操细节,这是整个系列中最重要、也最容易被低估的一章。

上一篇:[(二)系统认知与效率]


权限的本质:能和不能做什么

在深入命令之前,先回到原点——什么是权限?

权限的本质只有一个:确定什么能做,什么不能做。 它是一张"允许清单",操作系统每收到一个操作请求,就去查这张清单——符合条件就放行,不符合就拒绝。

为什么需要权限?

两个核心原因:

  1. 防止误操作——阻止一个手滑的 rm -rf 毁掉全系统,阻止一个错误的配置修改让服务瘫痪
  2. 隔离用户——Linux 是多用户操作系统。张三的文件不该被李四看,A 部门的代码不该被 B 部门改。权限划出了每个人的活动边界

理解权限有一个关键认知:权限的首要限制对象是人(身份),不是文件。 权限始终围绕"谁(角色)能对什么资源做什么操作(属性)"展开。"权限"和"角色"是绑定的——对一个文件做操作之前,系统先看你是谁,再决定放不放行。

用公式表达:

权限 = 角色(拥有者 / 所属组 / other)+ 属性(读 r / 写 w / 执行 x)

其中所属组的存在是为了更精细化的权限管理:一个文件的所有者可以把它共享给同组的同事,同时对外人保密。而 other 是"以上都不是"的兜底角色——无需事先记录,只要不匹配前两种,就按 other 的规则来。


用户分类

Linux 下有两类用户:

  • 超级用户(root):命令提示符 #,可以做任何事情,不受权限限制
  • 普通用户:命令提示符 $,仅在自己的权限范围内操作

重点:root 不受限。 Linux 的权限检查对 root 完全不生效——root 可以读写执行任何文件,可以进入任何目录。这也是为什么日常操作绝不建议用 root 登录。

su 用户名    # switch user — 切换用户
su root      # 切换到 root(root 可省略)
su -         # 加载目标用户环境变量(推荐)

su 的问题是:一旦切到 root,你就一直以最高权限运行——直到手动退出。敲的每一条命令都不受限制,包括那个写错路径的 rm -rf

sudo(superuser do)— 短暂提权

sudo(superuser do) 的设计思路更安全:只让当前这一条命令以 root 身份执行,执行完立即回到普通用户。

从实现上看,Linux 只安装一套软件,sudo 提供了一个类似白名单的机制——管理员通过编辑 /etc/sudoers 配置文件,精确控制哪些用户可以使用 sudo 执行哪些命令。

sudo yum install -y vim       # 以 root 身份安装软件包
sudo systemctl restart nginx  # 以 root 身份重启服务
sudo -i                       # 短暂进入 root shell(用 exit 退出)

sudo vs su 的核心区别:

su sudo
权限范围 整个 shell 会话 仅当前一条命令
需要谁的密码 目标用户(如 root)的密码 当前用户的密码
安全审计 无记录 每次执行记录在 /var/log/secure
推荐程度 仅特殊情况 日常首选

生产环境中,sudo 是绝对的主流——管理员不需要知道 root 密码,只需将自己的账号加入 sudoers 授权文件,就能在需要时临时提权。root 密码可以安全地封存甚至禁用,这才是真正的权限最小化。

💡 Ubuntu 默认禁用 root 直接登录,一切特权操作都走 sudo。这不是偷懒,是刻意为之的安全设计。

退出管理员身份

无论用了 su 还是 sudo -i,当前 shell 变成了 root——怎么退回去?

exit        # 退出当前 shell,回到上一个用户
logout      # 等价于 exit,在登录 shell 中使用

Ctrl+D 也可以——它向 shell 发送 EOF 信号,效果等同于 exit

验证自己当前是谁:

whoami      # 显示当前用户名
id          # 显示当前用户的 UID、GID 和所属组

提示符也能帮你判断:$ 是普通用户,# 是 root。养成敲命令之前瞥一眼提示符的习惯——以 root 身份执行日常操作,是 Linux 新手最容易犯的危险习惯之一。


文件访问者分类

每个文件面向三类"访问者":

符号 角色 含义
u User(所有者) 文件的创建者
g Group(所属组) 文件所有者所在的用户组
o Others(其他人) 既非所有者也不在所属组的用户

关键规则:在 CentOS 下,用户角色的确定只有一次,按照 拥有者 → 所属组 → other 的顺序依次匹配。 一旦匹配成功就不再往下判断。也就是说,如果你是文件的所有者,系统只用 owner 权限来判断你能做什么——即使所属组有更宽松的权限也不会生效,因为你已经被"认领"为 owner 了。


文件类型与权限

ls -l 输出的第一个字符代表文件类型

字符 类型
- 普通文件
d 目录
l 软链接(类似 Windows 快捷方式)
b 块设备文件(硬盘等)
c 字符设备文件(终端等)
p 管道文件
s 套接字文件

随后九个字符,每三个一组,分别代表 u / g / o 的读(r)写(w)、**执行(x)**权限。- 表示不具备该权限。

-rwxr-xr--

解读:普通文件,所有者可读可写可执行(rwx),所属组可读可执行(r-x),其他人仅可读(r–)。

重要:可执行权限(x)不意味文件一定可以被执行。 x 权限只是"允许尝试执行"的通行证——如果你给一个文本文件加了 x 权限试图运行它,系统能做的也只是尝试去执行,至于能不能执行起来,取决于文件内容本身是否是可执行格式(如 ELF 二进制或带 shebang 的脚本)。权限管的是"准不准",不是"能不能"。


权限的数字表示

权限 字母 数字值
r 4
w 2
执行 x 1

rwx = 4+2+1 = 7,rw- = 4+2 = 6,r-- = 4。于是 rwxr-xr-- = 754。

八进制表示法可以覆盖从完全开放到完全封闭的整个权限范围:chmod 777 赋予所有人全部权限,chmod 000 则让所有人(除 root)都无法访问。


chmod(change file mode bits)— 修改权限

# 字符表示法:u/g/o/a ± r/w/x
chmod u+wr,g-wr,o+x my.txt       # 所有者加读写、所属组去读写、其他人加执行
chmod a+x my.txt                 # 所有人加执行权限
chmod u+w /home/abc.txt          # 所有者增加写权限
chmod o-x /home/abc.txt          # 其他用户移除执行权限
chmod a=r /home/abc.txt          # 所有人仅保留读权限

# 八进制(数字)表示法
chmod 664 /home/abc.txt          # rw-rw-r--
chmod 755 script.sh              # rwxr-xr-x
chmod 777 shared_dir/            # rwxrwxrwx(完全开放)
chmod 000 secret.txt             # ---------(除 root 外无人能访问)

# 递归修改
chmod -R 755 /path/to/dir/

重点:用户只能修改自己的文件权限。 如果你不是文件的所有者(且不是 root),chmod 会直接报 Operation not permitted。系统同样会拒绝任何无权限的访问,返回 Permission denied


chown(change file owner)与 chgrp(change group ownership)— 更改归属

chown user1 f1                  # 将 f1 的所有者改为 user1
chown -R user1 filegroup1/      # 递归修改整个目录

chgrp users /abc/f2             # 将 f2 的所属组改为 users

注意:系统默认不允许把文件权限"送给"别人。 只有 root 或具有更高权限的用户才能执行 chown/chgrp——否则普通用户之间随意转交文件所有权会成为安全漏洞。


umask(user file-creation mode mask)— 默认权限掩码

创建新文件或目录时,权限并不是凭空产生的——每种文件类型都有一个起始权限,再经过 umask 的"裁剪",才形成最终权限。

  • 普通文件:起始权限默认为 0666rw-rw-rw-),默认不带可执行权限——这是合理的,因为大多数新建文件(源代码、配置文件、文档)都不该默认可执行
  • 目录文件:起始权限默认为 0777rwxrwxrwx),默认携带可执行权限——因为进入目录需要 x,如果没有 x,连 cd 都进不去

最终权限的计算公式:

最终权限 = 起始权限 & (~umask)

umask 的实质目的:凡是出现在 umask 里的权限位,都不应该出现在最终权限里。 可以理解为一张"创建时自动抹除的权限清单"。

umask           # 查看当前掩码(root 默认 0022,普通用户默认 0002)
umask 044       # 设置掩码

以普通文件为例:起始 0666,umask 0002,最终权限 = 666 & ~002 = 666 & 775 = 664rw-rw-r--)。这就是为什么 touch 一个新文件后,ls -l 看到的是 664 而不是 666

为什么需要 umask?

  1. 系统可配置,灵活满足需求——默认权限由系统决定,你无法在创建文件之前逐一手动指定权限。umask 提供了一种全局的"安全默认值",确保所有新文件都出生在你设定的安全基线之上
  2. 代码可控——在特殊场景(比如安全敏感的服务)下,通过配置 umask 可以保证进程创建的所有文件默认就是受限的,不需要在代码中额外 chmod

目录权限的深层理解

目录权限和普通文件权限有着本质不同的含义:

权限 对普通文件的含义 对目录的含义
r(读) 可以读取文件内容 可以 ls 查看目录内有哪些文件
w(写) 可以修改文件内容 可以在目录内创建/删除文件
x(执行) 可以执行该文件 可以 cd 进入该目录

几个需要牢记的规则:

  • 想要进入目录,必须拥有 x 权限——没有 x,连 cd 都执行不了
  • 如果对目录没有 r 权限,无法查看目录内部的文件列表——你知道里面有文件也 ls 不了
  • 如果对目录没有 w 权限,无法在该目录内新建或删除文件——哪怕你对目录内的文件本身拥有全部权限也没用

一个容易犯错的组合:目录有 r 但没有 x。此时无法 cd 进入目录,也无法访问目录内的文件——读权限在目录上的含义是"读取目录项列表",不是"读取目录下的文件内容"。

💡 默认情况下,任何普通用户都无权进入其他用户的家目录/home/username/)。这是 Linux 多用户隔离的基本设计——你的家目录就是你的私人空间。


为什么文件能删除但不能写?

这是一个经典的 Linux 权限面试题。

设想场景:你对 /shared/report.txt 拥有 rw- 权限,可以自由读写。但你尝试删除它时却失败了。为什么?

答案:删除一个文件,需要的是该文件所在目录的写权限(w),而不是文件自身的写权限。 删除的本质是从目录中移除一条"文件名 → inode"的映射记录——这个操作修改的是目录文件的内容,不是被删除文件的内容。所以系统检查目录的 w 权限,而不是文件的 w 权限。

这引申出一个实践原则:两个用户需要共享文件时,应该把目录放在一个双方都有 w 权限的公共位置(如 /tmp/ 或专门的共享目录),而不是放在某人的家目录下。


粘滞位(Sticky Bit)

上一条规则的直接后果:一个目录有写权限,就意味着任何能在该目录中操作的用户都能删除目录中的任何文件——即使这个文件不属于他。这在共享目录中显然是不合理的。

粘滞位解决了这个问题:

chmod +t /shared_dir/    # 给目录添加粘滞位
# 数字表示法:在权限前面加 1,如 chmod 1777 /shared_dir/

设置粘滞位后,目录下的文件只能由以下角色删除:

  1. 超级管理员(root)
  2. 该目录的所有者
  3. 该文件的所有者

/tmp 目录就是粘滞位的典型应用——每个用户都能在里面创建临时文件,但不能删除别人的。ls -ld /tmp 可以看到它的权限第一位是 tdrwxrwxrwt


本节要点

  • 权限 = 角色(u/g/o)+ 属性(r/w/x),权限的首要限制对象是人(身份),不是文件。数字表示法(4/2/1)在脚本中更常用,八进制从 000 到 777
  • CentOS 下角色确定只有一次,按 owner → group → other 顺序匹配,一旦命中就不再往下判断
  • root 不受限——Linux 的权限检查对 root 完全不生效,日常操作绝不用 root 登录
  • 可执行权限 ≠ 文件一定可以执行——x 只代表"允许尝试",能不能真正执行取决于文件内容
  • 用户只能修改自己的文件权限chown/chgrp 不允许普通用户把权限转交给别人——只有 root 能做
  • sudo 只提权一条命令,su 提权整个 shellsudo 通过 /etc/sudoers 白名单控制,生产环境首选 sudo
  • exit / Ctrl+D 退出当前 shellwhoami 确认身份。看一眼提示符——$ 还是 #——比什么都管用
  • 目录的 x 权限决定能不能进去,r 权限决定能不能列出内容,w 权限决定能不能在里面新建/删除文件。三者是独立的
  • 删除文件需要的是目录的 w 权限,不是文件自身的 w 权限——因为删除是从目录中移除一条映射,修改的是目录而非文件
  • 任何人无权进入别人的家目录——Linux 多用户隔离的基本设计
  • 粘滞位(Sticky Bit)让共享目录下的文件只能由文件所有者删除/tmp 是典型应用
  • 普通文件起始权限 666,目录起始权限 777。最终权限 = 起始权限 & (~umask)——umask 是你设置"安全默认值"的工具,凡是出现在 umask 里的权限都不该出现在最终权限里

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐