前言

Linux 是一个多用户操作系统。同一台机器上可以同时存在很多用户,每个用户又可能属于不同的用户组。如果所有人都能随意读取、修改和删除彼此的文件,系统中的数据就很难得到保护。

因此,当一个进程准备访问文件或目录时,Linux 会结合当前进程的身份、目标文件的所有者和所属组,以及对应的权限位,判断这次操作是否允许。

本文主要介绍:

  1. root 与普通用户的区别,以及 susudo 的基本使用;
  2. 文件所有者、所属组和其他用户三种访问者身份;
  3. ls -l 中的文件类型与九个权限位;
  4. rwx 对普通文件和目录的不同含义;
  5. 使用字符方式和八进制方式理解权限;
  6. 使用 chmodchownchgrp 修改权限与归属;
  7. umask 如何影响新建文件和目录;
  8. 共享可写目录为什么需要粘滞位。

Linux 权限并不只是记住几个命令,更重要的是弄清楚:谁以什么身份,对什么对象,准备进行什么操作。


一、Linux 中的用户身份

1. root 与普通用户

Linux 中常见的用户可以先分成两类:

  • 超级用户 root:拥有最高级别的系统管理权限,通常能够绕过普通的自主访问控制;
  • 普通用户:只能在系统授予的范围内进行操作。

在很多终端环境中,root 的命令提示符通常以 # 结尾,普通用户通常以 $ 结尾:

[root@host ~]#
[alice@host ~]$

不过提示符可以被修改,所以不能只靠 #$ 判断当前身份。更可靠的方式是使用:

whoami
id
groups

它们分别可以查看当前用户名、用户与组 ID,以及当前用户加入的用户组。

root 权限很高,但并不意味着任何时候都应该使用 root。错误地执行删除、覆盖或权限修改命令时,高权限反而会让误操作造成更大影响。平时优先使用普通用户,在确实需要管理权限时再进行提权更加安全。

2. 使用 su 切换用户

su 用于切换当前用户身份:

su 用户名

例如切换到用户 alice

su alice

如果希望同时切换到目标用户的登录环境,一般使用:

su - alice

两种写法的区别可以简单理解为:

  • su alice:主要切换用户身份,当前目录和部分环境可能继续保留;
  • su - alice:按照一次完整登录来切换,进入目标用户的家目录并加载其登录环境。

普通用户切换到其他用户时,通常需要输入目标用户的密码;root 切换到普通用户时通常不需要。操作完成后可以使用 exit 返回原来的 shell:

exit

二、文件访问者的三种分类

一个文件或目录的九个基本权限位,会按照三个字符一组分成三组:

简写英文含义
uuser / owner文件或目录的所有者
ggroup文件或目录所属组中的用户
oothers既不是所有者,也不属于匹配所属组的其他用户
aall在修改权限时表示 ugo 全部用户

这里要区分两个容易混淆的概念:

  • 用户是谁,由用户 ID 表示;
  • 文件属于哪个用户、哪个组,由文件的所有者和所属组记录。

在只考虑传统 u/g/o 权限位,暂时不考虑 POSIX ACL、SELinux 等附加机制时,系统会按照下面的顺序匹配权限类别:

  1. 如果进程的有效用户 ID 与文件所有者相同,就使用 u 权限;
  2. 否则,如果文件的组 ID 与进程的有效组 ID 或任一附加组 ID 匹配,就使用 g 权限;
  3. 前两项都不满足时,才使用 o 权限。
    在这里插入图片描述

需要注意,三组权限并不会相加。

例如某文件权限为:

----rwx---

假设文件所有者正是当前用户,那么系统会直接选择所有者的第一组 ---,不会因为当前用户同时属于文件所属组,就再把组权限 rwx 加过来。


三、使用 ls -l 查看文件属性

使用 ls -l 可以查看文件和目录的详细信息:

ls -l

可能得到:

-rwxr-xr-x 1 root root 8360 Jul 16 15:44 hello
-rw-r--r-- 1 root root   75 Jul 16 15:43 hello.c

在这里插入图片描述

以第一行为例:

-rwxr-xr-x 1 root root 8360 Jul 16 15:44 hello
│└─┬─┘└─┬─┘└─┬─┘ │  │    │    │        │
│  │    │    │   │  │    │    │        └── 文件名
│  │    │    │   │  │    │    └────────── 时间信息
│  │    │    │   │  │    └─────────────── 文件大小
│  │    │    │   │  └──────────────────── 所属组
│  │    │    │   └─────────────────────── 所有者
│  │    │    └─────────────────────────── 其他用户权限
│  │    └──────────────────────────────── 所属组权限
│  └───────────────────────────────────── 所有者权限
└──────────────────────────────────────── 文件类型

最前面的十个字符最值得关注:

- rwx r-x r-x
│  │   │   └── other
│  │   └────── group
│  └────────── owner
└───────────── 文件类型

1. 第一个字符表示文件类型

Linux 中常见的文件类型标志如下:

字符文件类型
-普通文件
d目录
l符号链接
b块设备文件,例如磁盘设备
c字符设备文件,例如终端设备
p管道文件
s套接字文件

所以权限字符串开头的 - 并不是“没有权限”,它表示这是一个普通文件。

2. 后九个字符表示基本权限

后九位按照 ownergroupother 分成三组,每组都按照 rwx 的固定顺序排列:

rwx rwx rwx
 u   g   o

如果某个位置显示 -,表示没有对应权限。例如:

rw-r-----

可以拆成:

rw-  r--  ---
 u    g    o

含义是:所有者可读可写,所属组只读,其他用户没有权限。


四、r、w、x 的真正含义

rwx 分别来自 readwriteexecute。但是同一个权限作用在普通文件和目录上时,含义并不相同。

在这里插入图片描述

1. 普通文件的 rwx

对于普通文件:

  • r:允许读取文件内容;
  • w:允许修改文件内容;
  • x:允许把文件作为程序执行。

需要注意,拥有 x 权限只代表系统允许尝试执行。文件本身还必须是有效的可执行程序,或者是带有正确解释器声明的脚本,否则仍然不能正常运行。

2. 目录的 rwx

对于目录:

  • r:允许读取目录项,也就是列出目录中保存了哪些名字;
  • w:允许修改目录项,例如创建、删除和重命名文件;
  • x:允许搜索、进入和穿过目录,并访问已知名称的目录项。

目录的 x 权限非常重要。没有 x 时,即使具有 r,也可能只能看到目录项名称,却无法正常取得其中对象的详细信息,更不能顺利进入目录。

可以将几种常见组合简单理解为:

目录权限常见表现
r-x可以列出目录内容,也可以进入并访问其中的对象
--x不能列出所有名字,但知道准确路径时可能访问对应对象
r--可以读取目录项名称,但无法正常进入、搜索目录
-wx不能列出全部名字,但可能创建、删除或重命名已知目录项

实际访问还会受到父目录权限、目标文件自身权限以及其他安全机制的共同影响。

3. 为什么没有文件写权限也可能删除文件

删除文件,本质上是在父目录中删除一个目录项。因此能否删除某个文件,主要检查父目录是否允许修改,而不是只看文件自身有没有 w

假设用户对目录拥有 wx,那么即使某个文件本身是只读的,该用户仍可能删除这个文件。文件自身的 w 主要决定能否修改文件内容,并不直接决定能否从父目录中移除它的名字。

这也是后面共享目录需要引入粘滞位的重要原因。


五、字符权限与八进制权限

1. rwx 对应的数字

每个权限字符都可以使用一个数字表示:

r = 4
w = 2
x = 1

同一组中具有什么权限,就把相应数字相加:

字符权限计算数字
rwx4 + 2 + 17
rw-4 + 26
r-x4 + 15
r--44
---00

在这里插入图片描述

例如:

rwxr-xr--

分组计算为:

rwx  r-x  r--
 7    5    4

因此它可以写成八进制权限 754

2. 常见权限值

权限值字符形式常见含义
600rw-------只有所有者可读写
640rw-r-----所有者可读写,所属组只读
644rw-r--r--所有者可读写,其他人只读
700rwx------只有所有者拥有全部权限
755rwxr-xr-x所有者全部权限,其他人可读可执行
777rwxrwxrwx所有人都拥有全部基本权限

777 虽然看起来最省事,但它往往把权限开放得过大。遇到“Permission denied”时,不应该直接把所有对象都改成 777,而是先判断真正缺少的是哪一类用户的哪一项权限。


六、使用 chmod 修改权限

chmod 用于修改文件或目录的权限:

chmod 权限 文件或目录

只有文件所有者或具有相应特权的进程才能修改权限。

1. 使用字符方式修改

字符方式的一般结构为:

用户类别  操作符  权限字符
 u/g/o/a   +/-/=     r/w/x

其中:

  • +:增加指定权限;
  • -:移除指定权限;
  • =:把该类别直接设置为给出的权限,未写出的权限会被清除。

常见例子:

# 给所有者增加执行权限
chmod u+x script.sh

# 移除所属组的写权限
chmod g-w data.txt

# 让其他用户只拥有读权限
chmod o=r data.txt

# 给所有用户增加读权限
chmod a+r readme.txt

=+ 不同。例如:

chmod a=x file

它不是“给所有人增加执行权限”,而是把所有人的权限都设置成只有 x,原有的 rw 会被清除。如果只是增加执行权限,应写成:

chmod a+x file

2. 使用八进制方式修改

chmod 664 data.txt
chmod 640 secret.txt
chmod 755 script.sh
chmod 700 private_dir

三位数字从左到右依次对应 ownergroupother

执行后可以使用 ls -l 验证:

ls -l data.txt

3. 递归修改

chmod -R 可以递归修改目录以及其中对象的权限:

chmod -R 755 some_dir

不过递归修改要格外谨慎。普通文件和目录对 x 的需求并不相同,直接把整个目录树统一改成 755,可能让原本不应该执行的普通文件全部得到执行位。修改前应先确认范围和目标权限。


七、修改所有者和所属组

权限位决定“能做什么”,所有者和所属组决定“使用哪一组权限”。它们是两个不同层面的问题。

1. chown 修改所有者

chown 新所有者 文件名

例如:

chown alice report.txt

也可以同时修改所有者与所属组:

chown alice:developers report.txt

递归修改目录树时使用 -R

chown -R alice:developers project_dir

在 Linux 中,把文件所有权转交给另一个用户通常需要管理员权限。

2. chgrp 修改所属组

chgrp 新组名 文件名

例如:

chgrp developers report.txt

递归修改:

chgrp -R developers project_dir

普通用户作为文件所有者时,通常只能把文件所属组改为自己所属的组;如果要改成任意其他组,就需要相应特权。具体结果还可能受到文件系统和安全策略限制。

修改后可以再次使用 ls -l 查看所有者和所属组字段。

3. 不要混淆 chmod、chown 和 chgrp

命令修改内容
chmodrwx 权限位
chown文件或目录的所有者,也可同时修改所属组
chgrp文件或目录的所属组

如果问题是用户被分到了 other 类别,只修改 rwx 不一定是最合理的办法;有时真正应该调整的是文件所属组,或者把用户加入合适的用户组。


八、umask:新建对象的权限掩码

1. umask 的作用

umask 用于查看或设置当前 shell 的文件创建掩码:

umask

常见输出为:

0022

创建普通文件和目录时,程序会先提出一个基础权限请求,再由 umask 屏蔽其中的部分权限位。

常见情况下:

普通文件的基础权限:0666
目录的基础权限:    0777

最终权限按照位运算理解为:

实际权限 = 基础权限 & ~umask

在这里插入图片描述

umask0022 时:

普通文件:0666 & ~0022 = 0644  -> rw-r--r--
目录:    0777 & ~0022 = 0755  -> rwxr-xr-x

普通文件的基础权限通常不带 x,是为了避免一个刚创建的普通文件默认就能被执行。需要执行脚本或程序时,再通过 chmod 明确添加执行权限。

2. umask 不是简单减法

有时 基础权限 - umask 恰好能得到相同结果,但这不是正确的一般规则。umask 的本质是屏蔽对应的权限位,应按照:

mode & ~umask

来理解。

3. 设置 umask

# 当前 shell 中设置为 0027
umask 0027

此时常见结果为:

新建普通文件:0640  -> rw-r-----
新建目录:    0750  -> rwxr-x---

umask 只影响之后新创建的文件和目录,不会自动修改已经存在的对象。它是进程的文件创建掩码属性,当前 shell 启动的子进程通常会继承这个值。

不同系统、发行版、用户配置和具体程序可能使用不同的初始掩码或基础模式,所以不要假设所有环境的默认值都完全相同。如果目录配置了默认 ACL,最终权限还可能受到 ACL 影响;本文的公式针对传统权限模型。


九、目录权限为什么尤其重要

1. 路径中的每一级目录都要能够穿过

访问下面的文件:

/home/alice/project/data.txt

系统不仅要检查 data.txt,还要逐级搜索 /homealiceproject。如果路径中某一级目录缺少 x 权限,即使最终文件本身是可读的,也可能无法访问。

因此遇到权限问题时,不能只查看目标文件:

ls -l data.txt

还应该检查路径中的目录权限,例如:

ls -ld /home /home/alice /home/alice/project

2. ls -l 与 ls -ld 的区别

ls -l some_dir

这会尝试列出 some_dir 中的内容。

ls -ld some_dir

这会查看目录对象本身的详细属性,而不是展开其内容。排查目录权限时,ls -ld 经常更加合适。

3. 文件删除由父目录管理

假设共享目录允许所有用户写入,那么不同用户就可能删除彼此创建的文件。即使某个文件是:

-rw-------

只要另一个用户对父目录拥有足够的 wx,仍然可能移除这个目录项。

对于真正需要多人写入的公共目录,简单地把权限设置成 777 并不能阻止互相删除,这时就需要粘滞位。


十、共享目录与粘滞位

1. 粘滞位解决什么问题

粘滞位不会主动授予目录写权限。在调用者本来就拥有目录所需 wx 权限的前提下,它会进一步限制目录项的删除与重命名:

  1. 具有相应特权的用户;
  2. 目录所有者;
  3. 被删除或改名对象的所有者。

其他普通用户即使能够在目录中创建自己的文件,也不能随意删除别人的文件。

在这里插入图片描述

2. 设置与查看粘滞位

给目录增加粘滞位:

chmod +t shared_dir

也可以使用数字形式:

chmod 1777 shared_dir

查看:

ls -ld shared_dir

可能得到:

drwxrwxrwt 2 root root 4096 Jul 18 10:00 shared_dir

最后一组执行位显示为小写 t,表示其他用户具有 x,同时目录设置了粘滞位。如果显示为大写 T,则表示设置了粘滞位,但该位置原本没有 x 权限。

系统中的 /tmp 就是常见例子:

ls -ld /tmp

通常能够看到类似 drwxrwxrwt 的权限。

需要注意,粘滞位主要限制目录项的删除与重命名,并不自动改变文件内容的读写权限。如果别人本来就对文件拥有 w,粘滞位不会因此禁止他修改文件内容。


十一、su 与 sudo 的区别

susudo 都与身份和授权有关,但用途不同:

命令主要作用
su切换到另一个用户并继续使用新的 shell
sudo按授权规则,以指定用户身份执行某一条命令

使用 sudo 执行管理命令:

sudo command

默认通常以 root 身份执行,也可以指定用户:

sudo -u alice command

是否能够使用 sudo,由系统的授权配置决定,并不是所有普通用户都天然拥有该能力。

如果确实需要管理 sudoers,应该使用 visudo 进行编辑和语法检查,不建议直接使用普通编辑器随意修改该文件。错误的配置可能导致管理权限不可用。

还要注意,sudo 是让某条命令以被授权的身份运行,它本身不会永久改变目标文件的 rwx 权限。文件权限仍然由 chmod 等命令管理。


十二、常见错误总结

1. 认为三组权限会叠加

系统会在 ownergroupother 中匹配一组使用,而不是把三组权限合并。

2. 认为目录有 r 就一定能进入

目录的 r 主要用于读取目录项名称,能否进入和穿过目录主要取决于 x

3. 认为文件不可写就不能删除

删除文件主要修改的是父目录。父目录的 wx 以及粘滞位规则更加关键。

4. 把权限全部开放成 777

解决权限问题时直接使用 chmod -R 777 风险很高。应该先判断缺少的是哪个用户类别、哪一项权限,并只开放实际需要的范围。

5. 把 umask 理解成普通减法

正确思路是屏蔽权限位:

实际权限 = 请求权限 & ~umask

6. 混淆 chmod 与 chown

chmod 修改权限位,chown 修改所有者,chgrp 修改所属组。权限位正确但归属不合理时,应先检查所有者和所属组。


十三、总结

本文整理了 Linux 权限管理中的核心内容。

Linux 会根据进程身份,把访问者匹配为文件所有者、所属组用户或其他用户,并只使用对应的一组 rwx 权限。使用 ls -l 时,第一个字符表示文件类型,后九位按照 ownergroupother 分成三组。

对于普通文件,rwx 分别表示读取、修改和执行;对于目录,它们分别表示列出目录项、修改目录项和搜索穿过目录。目录权限直接影响路径访问、文件创建以及删除操作,所以排查问题时不能只盯着目标文件。

chmod 可以使用字符方式或八进制方式修改权限,chownchgrp 分别调整所有者和所属组。umask 通过屏蔽权限位影响新创建的文件和目录,但不会追溯修改已有对象。

最后,在多人可写的共享目录中,单纯使用 777 会让用户可能删除彼此的文件。粘滞位可以在保留公共写入能力的同时,限制目录项的删除和重命名。理解这些规则后,再遇到 Permission denied 时,就能从用户身份、权限类别、文件权限、目录权限和所有权几个方向逐步定位问题。


Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐