文件权限(文件模式)指定谁可以在 Linux 系统上访问、改变或执行一个文件。它确保只有授权的用户和进程可以访问文件和目录。
通过命令 ls -l
就可以获得文件的权限、属主与属组等信息:
ls -l /etc/hosts
-rw-r--r-- 1 root root 186 Aug 27 18:31 /etc/hosts
这些信息表示为:
- 文件类型及权限:
-rw-r--r--
; - 硬链接数量:
1
; - 文件属主:
root
; - 文件属组:
root
; - 文件的字节数大小:
186
; - 最后修改日期及时间:
Aug 27 18:31
; - 文件名:
/etc/hosts
;
属主、属组以及其他用户
对于每个文件来说,权限被分配给三种不同类别的用户:
- 属主:文件和目录所属于的用户;
- 属组:属于由一个或多个用户组成的组,属组用户被文件和目录的属主授予访问权。
- 其他用户:在 Unix 术语里这叫作「世界(world)」的(即除了属主与属组外的)其他用户授权。
以 -rw-r--r--
为例,在之前的文章有提到第一个字母表示文件类型,剩余的每三个字母分别表示属主、属组和世界(其他用户)的权限:
文件类型 | 属主(Owner) | 属组(Group) | 世界(World) |
---|---|---|---|
- | rw- | r-- | r-- |
关于第一个字母表示的文件类型:
- 普通文件:
-
- 目录:
d
- 字符设备文件:
c
- 块设备文件:
b
- 本地域套接字:
s
- 具名管道(FIFO):
p
- 符号链接:
l
读取、写入和执行
举个例子,-rwxr-r--
表示这是一个普通文件,属主拥有读取 r(ead)
、写入 w(rite)
及执行 x(ecute)
权限,而属组和世界(其他用户)均有读取但没有写入和执行权限。
权限 | 文件 | 目录 |
---|---|---|
r(ead) | 允许打开和读取文件 | 允许列出目录文件(需同时含有执行权限) |
w(rite) | 允许将文件写入或截断,但不允许重命名或删除文件(由目录属性决定)。 | 允许在目录内创建、删除及重命名文件(需同时含有执行权限) |
x(ecute) | 允许将文件视为程序并执行,用脚本语言编写的程序文件也必须设置为可读才能执行 | 允许进入该目录 |
- | 无权限 | 无权限 |
❓ 你可能对属组还不是很明白,举个例子有这么一个目录:
drwxr-x--- 3 a www 4096 Mar 30 15:30 wwwroot
属主是用户 a,属组是 www。这时用户 b 没有权限的,因为其他用户权限是
---
。
但让用户 b 加入到名为 www 到用户组就可以拥有权限r-x
。
💡思考
那么当一个文件的属主没有写入权限而属组有写入权限时,如:
-----w---- 2 user1 group1 4.0K Aug 23 08:45 README
注意 user1 用户属于 group1 用户组,这时可以写入吗?
这是一个权限冲突的问题,属主权限是 ---
,属组权限是 -w-
,当遇到这样的情况时以属主权限为准,即便该用户属于有写入权限的用户组。
修改文件权限:chmod
**文件和目录只有其属主或 root 用户通过 chmod
(Change Mode)命令修改文件或目录的文件模式(权限)。
chmod
命令有八进制表示法和符号表示法两种模式表示方式。
八进制表示法
八进制 | 二进制 | 模式 |
---|---|---|
0 | 000 | --- |
1 | 001 | --x |
2 | 010 | -w- |
3 | 011 | -wx |
4 | 100 | r-- |
5 | 101 | r-x |
6 | 110 | rw- |
7 | 111 | rwx |
举个例子:
mkdir Documents && ls -l
drwxr-xr-x 2 conners conners 4096 Apr 8 11:32 Documents
这里新建了一个名为 Documents
的目录,并且可以看到权限是 rwxr-xr-x
。
按照八进制表示法就是 755
,也就是依照 3 个八进制数位表示属主、属组与其他用户的权限。
7 5 5
user group world
r+w+x r+x r+x
4+2+1 4+0+1 4+0+1 = 755
那么如果想要将其他用户的权限禁止掉,即修改为 rwxr-x---
就可以使用八进制表示法:
# chmod <八进制表示法> <目标文件或目录>
chmod 750 Documents
符号表示法
符号 | 含义 |
---|---|
u | 属主(user 缩写) |
g | 属组(group 缩写) |
o | 其他用户(other 缩写) |
a | 所有(all 缩写,等同于 u、g、o 一起设置) |
+ | 添加权限 |
- | 移除权限 |
\= | 只赋予指定权限并移除其他权限 |
举几个例子:
# 为指定文件或目录的属组添加写入权限
chmod g+w <目标文件>
# 移除属主、属组与其他用户的写入权限
# 可以进一步简写为 -w 省去 a
chmod a-w <目标文件>
# 可以同时添加多个权限,如为属组同时添加写入与执行权限
chmod g+wx <目标文件>
# 等号会移除其他权限
# 如下,为属组与其他用户设置为仅有读取与执行权限,如果原有写入权限会被禁用
chmod go=rw <目标文件>
# 一次性为属主、属组与其他用户设置不同权限时,可用英文逗号隔开
chmod u+x,go=rx <目标文件>
💡 可以使用 -v
选项得出修改前后的差别及八进制表示:
chmod -v 755 file.txt
mode of 'file.txt' changed from 0644 (rw-r--r--) to 0755 (rwxr-xr-x)
复制已有文件的权限
可以使用 --reference
选项复制已有文件的权限:
# chmod --reference=<被复制权限文件> <复制权限文件>
chmod --reference=a.sh b.sh
如上,文件 b.sh
就拥有了和 a.sh
一样的文件权限。
递归设置子目录文件权限
chmod
还可以使用 -R
选项以递归的方式更新目录内所有文件的权限。但注意目录下的内容及子目录未必都是相同的属性,比如有的是可执行文件有的是文本文件。
在使用 chmod -R
进行执行权限调整需要谨慎,它不会去管执行权限对目录和普通文件有不同的含义。前面说过对于目录 x
表示进入目录,对于普通文件 x
表示执行。
针对这个问题,也就是如果只想对文件进行一个递归设置,但目录不要进行相应权限设置,可以搭配 find
命令:
find ~ -type f -exec chmod 640 {} \;
上面这条命令表示使用 fimd
查找主目录(~
)下的普通文件(-type f
),执行命令(-exec
),命令为 chmod 640
,针对查找到的文件({}),命令结束(\;
)
修改文件属主与属组:chown 与 chgrp
使用 chown
和 chgrp
命令可以用于改变文件的属主和属组。
只有 root 用户可以改变文件的属主,普通用户只有在拥有该文件并且只能更改为其所属的组时才能更改该文件的属组,而 root 用户可以更改所有文件的属组。
修改文件的属主:
sudo chown <目标用户> <文件名>
在用户组前加上冒号即为修改文件的属组,属主不变:
chown :<目标群组> <文件名>
将两者结合,修改目录 wwwroot
的属主为 nginx
,属组为 web
:
# -R 选项用于递归修改目录下的子文件及子目录
sudo chown -R nginx:web wwwroot
除了使用 chown :<目标属组> <文件名>
,使用 chgrp
命令也可以达到相同效果:
sudo chgrp <目标群组> <文件名>