Linux 权限详解:从 rwx、chmod 到 umask、目录权限与粘滞位

头像

🔥 星恒随风: 个人主页
❄️ 个人专栏: 《指针合集》 《C语言基础》 《数据结构》 《机器学习导论》 《前端基础》 《python基础》 《C++从入门到入土》 《Linux的学习之旅》
✨ 数据即知识,压缩即智能

文章目录

前言

上一篇文章最后提到,Linux 权限系统主要解决两个问题:

谁在访问文件?
他可以对文件做什么?

Linux 是一个多用户系统。

同一台主机上可能同时运行:

普通用户的程序
Web 服务
数据库服务
定时任务
系统管理工具

如果它们都可以不受限制地读取、修改和删除所有文件,系统几乎无法正常管理。

因此,Linux 会为文件和目录记录:

文件类型
文件拥有者
文件所属组
拥有者权限
所属组权限
其他用户权限

本文将完整讲解:

  • 怎样阅读 ls -l
  • Linux 常见文件类型
  • rwx 的含义
  • 文件权限与目录权限的区别
  • 字符权限和八进制权限
  • chmod 修改权限
  • chown 修改拥有者
  • chgrp 修改所属组
  • umask 如何影响默认权限
  • 为什么有时能删除一个没有写权限的文件
  • 粘滞位怎样保护共享目录

一、先学会阅读 ls -l

创建一个测试环境:

[root@xxx ~]# mkdir -p /root/permission_demo
[root@xxx ~]# cd /root/permission_demo
[root@xxx permission_demo]# touch demo.txt
[root@xxx permission_demo]# mkdir project

查看详细信息:

[root@xxx permission_demo]# ls -l
total 0
-rw-r--r-- 1 root root 0 Aug 2 18:10 demo.txt
drwxr-xr-x 2 root root 6 Aug 2 18:10 project

以文件这一行为例:

-rw-r--r-- 1 root root 0 Aug 2 18:10 demo.txt

可以拆分成:

-rw-r--r--   权限和文件类型
1            硬链接数量
root         文件拥有者
root         文件所属组
0            文件大小
Aug 2 18:10  最近修改时间
demo.txt     文件名

本文重点关注前面三部分:

-rw-r--r--
root
root

二、权限字符串的十个字符

权限字段通常包含十个字符:

-rw-r--r--

可以划分为:

- | rw- | r-- | r--
↑    ↑     ↑     ↑
类型  u     g     o

其中:

第 1 个字符:文件类型
第 2~4 个字符:拥有者权限
第 5~7 个字符:所属组权限
第 8~10 个字符:其他用户权限

也就是:

类型 | user | group | others

例如:

-rwxr-x---

表示:

-    普通文件
rwx  拥有者可读、可写、可执行
r-x  所属组可读、不可写、可执行
---  其他用户没有权限

三、Linux 中的常见文件类型

权限字符串的第一个字符表示文件类型。

3.1 -:普通文件

-rw-r--r--

普通文件包括:

文本文件
源代码
可执行程序
图片
压缩包
日志

Linux 判断文件类型时,并不只依赖扩展名。

例如:

main.cpp
main
README
data.bin

都可能是普通文件。

3.2 d:目录

drwxr-xr-x

目录本质上保存了一组文件名与文件对象之间的映射关系。

3.3 l:符号链接

lrwxrwxrwx

符号链接类似一种路径引用:

链接文件 → 目标路径

创建符号链接:

[root@xxx permission_demo]# ln -s demo.txt demo_link

查看:

[root@xxx permission_demo]# ls -l demo_link
lrwxrwxrwx 1 root root 8 Aug 2 18:20 demo_link -> demo.txt

3.4 p:命名管道

prw-r--r--

命名管道可以让进程通过文件系统中的名字交换数据。

3.5 c:字符设备

crw-rw-rw-

字符设备通常按照字符流方式传输数据,例如部分终端设备。

3.6 b:块设备

brw-rw----

块设备通常以数据块为单位访问,例如磁盘设备。

3.7 s:套接字文件

srwxr-xr-x

本地进程可以通过 Unix Domain Socket 进行通信。

3.8 使用 file 识别文件类型

基本语法:

file 文件名

例如:

[root@xxx permission_demo]# file demo.txt
demo.txt: empty

查看可执行程序:

[root@xxx permission_demo]# file /usr/bin/ls
/usr/bin/ls: ELF 64-bit LSB pie executable ...

查看目录:

[root@xxx permission_demo]# file project
project: directory

file 会根据文件内容和元数据进行判断,而不只是看文件名后缀。


四、Linux 中的三类访问者

对一个文件来说,访问用户会被归入三个范围之一。

4.1 u:拥有者

user

通常是创建文件的用户。

例如:

-rw-r----- 1 root developers 100 demo.txt

拥有者是:

root

4.2 g:所属组

group

文件会关联一个用户组。

上例中的所属组是:

developers

属于该组的用户会使用中间三位权限:

r--

4.3 o:其他用户

others

既不是文件拥有者,也没有通过所属组匹配到的用户,使用最后三位权限。

4.4 a:所有用户

chmod 中:

a

表示:

all

也就是:

u + g + o

4.5 权限匹配不是三组叠加

假设权限是:

-rw----r--

某用户是文件所属组成员,那么系统检查的是:

group 的 ---

不会因为 othersr--,就再退回去使用其他用户权限。

权限匹配通常是:

先判断是不是拥有者
不是,再判断所属组
仍不是,最后使用 others

五、r、w、x 对普通文件的含义

5.1 r:读取文件内容

r = read

拥有文件读权限,通常可以执行:

cat file.txt
less file.txt
head file.txt

取消读权限:

chmod u-r file.txt

普通拥有者再次读取时可能看到:

Permission denied

5.2 w:修改文件内容

w = write

拥有写权限,通常可以:

覆盖文件内容
追加文件内容
使用编辑器保存修改
截断文件

例如:

echo "new content" > file.txt

需要文件写权限。

5.3 x:执行文件

x = execute

拥有执行权限,表示可以把文件当作程序启动。

创建脚本:

[root@xxx permission_demo]# cat > hello.sh <<'EOF'
#!/bin/bash
echo "hello Linux"
EOF

初始权限可能是:

[root@xxx permission_demo]# ls -l hello.sh
-rw-r--r-- 1 root root 31 Aug 2 18:30 hello.sh

直接执行:

[root@xxx permission_demo]# ./hello.sh
bash: ./hello.sh: Permission denied

增加执行权限:

[root@xxx permission_demo]# chmod u+x hello.sh
[root@xxx permission_demo]# ./hello.sh
hello Linux

5.4 有执行权限不代表文件一定能正常运行

即使设置了 x,文件还需要满足对应程序格式。

例如一个普通文本文件:

chmod +x notes.txt

虽然拥有执行权限,但它未必是合法的二进制程序或脚本。

因此:

执行权限:允许尝试执行
文件格式:决定能否正确执行

六、r、w、x 对目录的含义

目录权限是最容易混淆的部分。

对目录来说,rwx 的含义与普通文件不同。

6.1 目录的 r:读取目录项列表

目录具有读权限,通常可以查看其中有哪些名字:

ls directory

也就是读取目录中保存的文件名列表。

6.2 目录的 w:修改目录项

目录具有写权限,表示可以修改目录中的文件名映射。

通常包括:

创建文件
删除文件
创建子目录
删除子目录
修改名称
移动目录项

这里修改的是目录内容,而不一定是某个文件的数据内容。

6.3 目录的 x:进入和穿过目录

目录具有执行权限,通常表示:

可以 cd 进入目录
可以通过该目录访问其中的文件
可以把该目录作为路径的一部分穿过

例如访问:

/home/student/project/main.cpp

需要对路径中的:

/home
/home/student
/home/student/project

都具有必要的执行权限。

6.4 只有 r,没有 x

假设目录权限为:

r--

用户可能能够读取到目录项名称,但无法正常进入目录,也无法通过这些名称访问文件属性和内容。

可以简单理解为:

知道里面有哪些名字
但无法真正沿路径访问它们

6.5 只有 x,没有 r

假设目录具有 x,但没有 r

--x

用户无法正常列出目录中的所有名字。

但是如果事先知道某个文件的准确名称,并且文件自身权限允许,仍可能通过完整路径访问它。

例如:

cat secret_dir/known.txt

6.6 删除文件看的是谁的权限?

删除文件,本质上不是修改文件内容,而是删除父目录中的一个目录项。

因此,能否删除某个文件,主要取决于:

父目录是否具有 w 权限
父目录是否具有 x 权限
是否受到粘滞位等额外规则限制

文件自身是否有 w 权限,并不是删除它的决定条件。

这就是为什么有时一个普通用户可以删除别人创建的文件:

他没有修改文件内容,但有权限修改父目录中的文件名映射。


七、权限的字符表示法

权限字符包括:

r
w
x
-

其中:

r:具有读权限
w:具有写权限
x:具有执行权限
-:不具有对应权限

例如:

rw-

表示:

可读
可写
不可执行
r-x

表示:

可读
不可写
可执行
---

表示没有任何基本权限。

完整权限:

rwxr-xr--

拆分后:

u:rwx
g:r-x
o:r--

八、权限的八进制表示法

Linux 权限还可以使用数字表示。

每一位权限对应一个数值:

r = 4
w = 2
x = 1

将同一组权限相加即可:

权限数值
---0
--x1
-w-2
-wx3
r--4
r-x5
rw-6
rwx7

例如:

rwxr-xr--

转换过程:

u:rwx = 4 + 2 + 1 = 7
g:r-x = 4 + 0 + 1 = 5
o:r-- = 4 + 0 + 0 = 4

因此数字权限是:

754

再例如:

rw-rw-r--

对应:

664

九、chmod:修改文件权限

chmod 是:

change mode

的缩写。

基本语法:

chmod [选项] 权限 文件或目录

通常只有:

文件拥有者
root

能够修改文件权限。


9.1 使用 + 增加权限

给拥有者增加执行权限:

[root@xxx permission_demo]# chmod u+x hello.sh

给所属组增加写权限:

chmod g+w demo.txt

给其他用户增加读权限:

chmod o+r demo.txt

给所有用户增加执行权限:

chmod a+x hello.sh

9.2 使用 - 删除权限

删除拥有者写权限:

chmod u-w demo.txt

删除所属组执行权限:

chmod g-x project

删除其他用户全部权限:

chmod o-rwx demo.txt

9.3 使用 = 直接设置权限

把拥有者权限设置为只读写:

chmod u=rw demo.txt

把所属组设置为只读:

chmod g=r demo.txt

把其他用户设置为空:

chmod o= demo.txt

一次设置三组:

chmod u=rw,g=r,o= demo.txt

结果是:

rw-r-----

9.4 使用八进制修改权限

设置为:

rw-rw-r--

命令:

chmod 664 demo.txt

设置为:

rw-r-----

命令:

chmod 640 demo.txt

设置脚本权限:

chmod 755 script.sh

对应:

rwxr-xr-x

9.5 递归修改目录权限

chmod -R 755 project

-R 表示递归修改目录及其内部所有内容。

这条命令需要谨慎,因为:

目录通常需要 x
普通文本文件通常不需要 x

直接把整个项目递归设置为 755,会让所有普通文件都获得执行权限。

更精确的做法是分别处理目录和文件:

find project -type d -exec chmod 755 {} \;
find project -type f -exec chmod 644 {} \;

十、chown:修改文件拥有者

chown 是:

change owner

的缩写。

基本语法:

chown [选项] 用户名 文件

例如:

[root@xxx permission_demo]# chown student demo.txt

查看:

[root@xxx permission_demo]# ls -l demo.txt
-rw-r--r-- 1 student root 0 Aug 2 18:40 demo.txt

拥有者已经由:

root

变成:

student

10.1 同时修改拥有者和所属组

chown student:developers demo.txt

结果:

拥有者:student
所属组:developers

只修改所属组也可以写成:

chown :developers demo.txt

10.2 递归修改

chown -R student:developers project

会递归修改目录及其中所有文件。

修改拥有者通常需要 root 权限。


十一、chgrp:修改文件所属组

chgrp 是:

change group

的缩写。

基本语法:

chgrp [选项] 用户组 文件

例如:

[root@xxx permission_demo]# chgrp developers demo.txt

递归修改目录:

chgrp -R developers project

chown 也可以同时修改所属组:

chown root:developers demo.txt

因此:

chgrp:专门修改所属组
chown:修改拥有者,也可以同时修改所属组

十二、umask:新文件权限为什么不是 666?

12.1 创建文件时的基础权限

普通文件的基础权限通常从:

0666

开始,也就是:

rw-rw-rw-

为什么没有执行权限?

因为系统不应该让每个新创建的文本文件和数据文件自动成为可执行程序。

目录的基础权限通常从:

0777

开始,也就是:

rwxrwxrwx

目录需要 x 才能进入和穿过。

12.2 为什么实际权限不同?

创建文件:

[root@xxx permission_demo]# touch new.txt
[root@xxx permission_demo]# ls -l new.txt
-rw-r--r-- 1 root root 0 Aug 2 18:50 new.txt

最终权限是:

644

而不是:

666

原因是新文件权限还会受到:

umask

影响。

12.3 查看 umask

[root@xxx permission_demo]# umask
0022

0022 表示屏蔽:

group 的写权限
others 的写权限

12.4 权限计算

PPT 中给出的计算关系是:

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

文件:

基础权限 0666
umask    0022
最终权限 0644

目录:

基础权限 0777
umask    0022
最终权限 0755

结果分别是:

文件:rw-r--r--
目录:rwxr-xr-x

需要注意,umask 不是简单的十进制减法。

不能机械理解为:

666 - 22 = 644

正确思想是屏蔽指定权限位。

12.5 修改 umask

将当前 Shell 的 umask 设置为:

[root@xxx permission_demo]# umask 0027

此时创建文件:

[root@xxx permission_demo]# touch private.txt
[root@xxx permission_demo]# ls -l private.txt
-rw-r----- 1 root root 0 Aug 2 18:52 private.txt

创建目录:

[root@xxx permission_demo]# mkdir private_dir
[root@xxx permission_demo]# ls -ld private_dir
drwxr-x--- 2 root root 6 Aug 2 18:52 private_dir

12.6 umask 只影响新创建的对象

修改 umask 不会自动改变已经存在的文件权限。

已有文件要通过:

chmod

修改。

12.7 常见 umask

常见配置包括:

0022:文件通常为 644,目录通常为 755
0002:文件通常为 664,目录通常为 775
0077:文件通常为 600,目录通常为 700

具体默认值由系统和用户配置决定,不应认为所有系统都完全相同。


十三、为什么普通用户能删除别人创建的文件?

假设一个共享目录具有:

rwxrwxrwx

用户 A 在其中创建:

abc.c

用户 B 可能仍然能够删除这个文件,即使文件拥有者是 A。

原因是删除操作修改的是:

父目录中的目录项

只要用户 B 对父目录具有:

w:修改目录项
x:穿过目录并访问其中对象

就可能删除其中的文件。

这说明:

文件内容修改权限

和:

目录项删除权限

不是同一件事。

13.1 文件写权限控制什么?

文件的 w 控制:

能否修改文件内容

13.2 目录写权限控制什么?

目录的 w 配合 x,控制:

能否添加、删除、重命名目录项

因此,一个文件即使是:

-r--r--r--

只要父目录允许,仍可能被删除。


十四、粘滞位:保护公共可写目录

14.1 公共目录的问题

有些目录需要所有用户都能创建文件,例如:

/tmp

如果目录权限只是:

rwxrwxrwx

那么所有用户不仅能创建文件,也可能删除其他用户的文件。

这显然不够合理。

14.2 设置粘滞位

可以给目录添加粘滞位:

[root@xxx ~]# chmod +t /shared

查看:

[root@xxx ~]# ls -ld /shared
drwxrwxrwt 2 root root 4096 Aug 2 19:00 /shared

注意最后一位:

t

它表示目录设置了粘滞位。

14.3 设置粘滞位后的删除规则

在设置了粘滞位的公共可写目录中,文件通常只能由以下用户删除或重命名:

1. root
2. 该目录的拥有者
3. 该文件的拥有者

其他普通用户即使对目录具有写权限,也不能随意删除别人的文件。

14.4 /tmp 的典型权限

查看:

[root@xxx ~]# ls -ld /tmp
drwxrwxrwt ... /tmp

常见数字表示是:

1777

其中:

777:所有用户可读、可写、可进入
1:粘滞位

14.5 删除粘滞位

chmod -t /shared

也可以使用数字权限:

chmod 0777 /shared

但执行前要明确是否真的需要取消公共目录的保护。


十五、目录权限组合总结

目录权限不能孤立理解。

15.1 r--

可以读取目录项名称
不能正常进入或穿过目录

实际操作能力非常有限。

15.2 --x

不能列出所有文件名
如果知道准确路径,可能访问其中对象

前提是目标文件自身权限允许。

15.3 r-x

可以查看目录内容
可以进入目录
不能创建、删除或重命名目录项

这是常见的只读目录权限。

15.4 -wx

不能正常列出全部文件名
但可能创建、删除或访问已知名称

这种组合比较少见,也容易造成难以理解的行为。

15.5 rwx

可以列出目录
可以进入目录
可以创建、删除和重命名目录项

十六、一个完整权限实验

16.1 创建共享组和目录

下面命令需要 root 权限:

[root@xxx ~]# groupadd developers
[root@xxx ~]# mkdir /shared_project
[root@xxx ~]# chown root:developers /shared_project
[root@xxx ~]# chmod 775 /shared_project

查看:

[root@xxx ~]# ls -ld /shared_project
drwxrwxr-x 2 root developers ... /shared_project

权限含义:

root:可读、可写、可进入
developers 组:可读、可写、可进入
其他用户:可读、不可写、可进入

16.2 创建私人目录

[root@xxx ~]# mkdir /private_data
[root@xxx ~]# chmod 700 /private_data

查看:

[root@xxx ~]# ls -ld /private_data
drwx------ 2 root root ... /private_data

只有拥有者能够:

查看
进入
创建和删除内容

16.3 创建公共临时目录

[root@xxx ~]# mkdir /shared_tmp
[root@xxx ~]# chmod 1777 /shared_tmp

查看:

[root@xxx ~]# ls -ld /shared_tmp
drwxrwxrwt 2 root root ... /shared_tmp

所有用户都能创建文件,但不能随意删除其他用户创建的文件。


十七、常见错误整理

17.1 认为 r、w、x 对文件和目录含义相同

普通文件:

r:读取内容
w:修改内容
x:作为程序执行

目录:

r:列出目录项
w:修改目录项
x:进入和穿过目录

17.2 认为文件没有写权限就不能删除

删除文件主要检查父目录权限,而不是只看文件自身的 w

17.3 认为有目录读权限就能 cd

进入目录主要依赖:

x

而不是 r

17.4 认为 chmod 777 是万能解决方案

chmod 777 文件

虽然可能暂时消除权限报错,但也会让所有用户获得过多权限。

更合理的做法是分析:

谁需要访问?
需要读、写还是执行?
应该修改拥有者、所属组还是权限位?

17.5 普通文本文件随意增加 x

普通配置文件、源代码和数据文件通常不需要执行权限。

常见配置:

普通文件:644
私人文件:600
可执行脚本:755 或 750
普通目录:755
共享组目录:775
私人目录:700

17.6 把 umask 当成减法

错误理解:

666 - 022

正确思路:

基础权限 & ~umask

17.7 使用 chmod -R 755 修改整个项目

这会让项目中的普通文件也获得执行权限。

更精确的做法:

find project -type d -exec chmod 755 {} \;
find project -type f -exec chmod 644 {} \;

17.8 忘记路径上每一级目录都需要 x

即使目标文件本身权限允许,如果路径中某一级目录没有 x,用户仍然无法访问目标。

17.9 把 root 权限当作日常默认权限

root 可以执行大量高风险操作。

日常开发更适合使用普通用户,只在必要时通过:

sudo 命令

临时获得管理权限。


十八、把整个权限体系串起来

Linux 权限判断可以抽象成下面的过程。

18.1 确定访问者身份

系统先确定当前进程属于哪个用户和哪些组:

id

18.2 确定使用哪组权限

依次判断:

当前用户是不是文件拥有者?
    ↓ 否
当前用户是否匹配文件所属组?
    ↓ 否
使用 others 权限

18.3 根据对象类型解释 rwx

如果目标是普通文件:

r:读内容
w:写内容
x:执行

如果目标是目录:

r:读取目录项
w:修改目录项
x:进入和穿过目录

18.4 检查额外限制

系统还可能继续检查:

父目录权限
粘滞位
访问控制列表 ACL
只读文件系统
安全模块规则
程序实际运行身份

在当前基础阶段,最重要的是先掌握:

拥有者、所属组、其他用户
+
文件类型
+
rwx
+
父目录权限

整个知识链可以表示为:

用户和用户组
      ↓
文件拥有者与所属组
      ↓
u、g、o 三组权限
      ↓
r、w、x 基本权限
      ↓
chmod 修改权限
      ↓
chown、chgrp 修改归属
      ↓
umask 影响新建文件默认权限
      ↓
目录权限决定创建和删除
      ↓
粘滞位保护公共目录

十九、总结

Linux 权限是理解:

权限属于谁
权限作用于什么对象
当前操作究竟修改文件内容还是目录结构

本篇重点包括:

  1. ls -l 的第一列由文件类型和三组权限组成
  2. u、g、o 分别表示拥有者、所属组和其他用户
  3. 普通文件的 r、w、x 表示读取、修改和执行
  4. 目录的 r、w、x 表示列出、修改目录项和穿过目录
  5. 权限可以使用字符或八进制表示
  6. chmod 用于修改权限
  7. chown 用于修改拥有者,也可同时修改所属组
  8. chgrp 专门修改所属组
  9. 普通文件基础权限通常是 0666
  10. 目录基础权限通常是 0777
  11. umask 会屏蔽新建对象的部分权限
  12. 删除文件主要取决于父目录的 w 和 x
  13. 粘滞位可以保护公共可写目录中的文件
  14. 不应使用 chmod 777 代替真正的权限分析

遇到权限错误时,可以按照下面的顺序排查:

whoami
id
ls -l 目标文件
ls -ld 父目录
namei -l 完整路径

然后依次确认:

当前用户身份
目标文件拥有者和所属组
文件自身权限
路径中各级目录权限
是否存在粘滞位或其他额外限制
  • Bash Reference Manual
Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐