本教程讲解如何使用 chmod 命令更改文件和目录的权限。
更喜欢可视化的方式?我们的交互式 chmod 计算器可以让你切换权限位并复制准确的命令。
Linux 文件权限概述
在继续之前,我们先解释一下 Linux 基本的权限模型。
Linux 中的每个文件和目录都有一个所有者和一个所属组,并被赋予针对三类不同用户(用户类别)的访问权限:
- 所有者(拥有该文件的用户)
- 所属组(文件所属组中的用户)
- 其他用户(其余所有人)
文件的所有权可以用 chown(更改所有者)和 chgrp(更改所属组)来修改。
每一类用户都适用三种文件权限类型:
- 读(r):查看文件内容,或列出目录内容
- 写(w):修改文件,或在目录中添加/删除项目
- 执行(x):将文件作为程序/脚本运行,或进入(cd)目录
特殊位(setuid、setgid、sticky)在执行权限位上会显示为 s、S、t 或 T。
这一概念让你可以指定哪些用户能够读取、写入或执行该文件。
可以使用 ls 命令查看文件权限:
ls -l filename.txt
-rw-r--r-- 12 linuxize users 12288 Apr 8 20:51 filename.txt |[-][-][-]- [------] [---] | | | | | | | | | | | | | +-----------> 7. Group | | | | | +-------------------> 6. Owner | | | | +--------------------------> 5. Alternate Access Method | | | +----------------------------> 4. Others Permissions | | +-------------------------------> 3. Group Permissions | +----------------------------------> 2. Owner Permissions +------------------------------------> 1. File Type
拆解说明:
- 第一个字符表示文件类型。它可以是普通文件( - )、目录( d )、符号链接( l ),或任何其他特殊类型文件。
- 接下来的九个字符表示文件权限,由三组、每组三个字符构成。第一组显示所有者权限,第二组显示所属组权限,最后一组显示其他用户权限。权限的具体含义会因文件类型不同而不同。
在示例( rw-r--r-- )中:
- 文件所有者拥有读和写权限( rw- )
- 所属组和其他用户只有读权限( r-- )
权限类型产生的效果会因对象是文件还是目录而不同:
文件上的权限
| 权限 | 字符 | 在文件上的含义 |
|---|---|---|
| 读 | - | 文件不可读。无法查看内容。 |
| r | 文件可读。 | |
| 写 | - | 文件内容无法通过普通写入更改。删除取决于父目录的权限。 |
| w | 文件内容可被更改。此权限本身并不允许删除该文件。 | |
| 执行 | - | 文件不可执行。 |
| x | 文件可作为程序/脚本被执行。 | |
| s | 若出现在 user 三元组中,则设置 setuid 位;若出现在 group 三元组中,则设置 setgid 位。同时意味着 x 标志被设置。当可执行文件上设置了 setuid 或 setgid 标志时,该文件将以文件所有者及/或所属组的权限运行。 | |
| S | 与 s 相同,但 x 标志未被设置。该标志在文件上很少使用。 | |
| t | 若出现在 others 三元组中,则设置 sticky bit。同时意味着 x 标志被设置。该标志在文件上无意义。 | |
| T | 与 t 相同,但 x 标志未被设置。该标志在文件上无意义。 |
目录(文件夹)上的权限
| 权限 | 字符 | 在目录上的含义 |
|---|---|---|
| 读 | - | 目录内容无法被列出。 |
| r | 目录内容可被列出。(例如,你可以用 ls 列出目录内的文件。) | |
| 写 | - | 目录内容无法被更改。 |
| w | 目录内容可被更改。(例如,你可以创建新文件、重命名文件、删除文件等。) | |
| 执行 | - | 无法进入该目录。 |
| x | 可使用 cd 进入并遍历该目录。 | |
| s | 若出现在 user 三元组中,则设置 setuid 位;若出现在 group 三元组中,则设置 setgid 位,同时意味着 x 标志被设置。当目录上设置了 setgid 标志时,在其中创建的新文件会继承该目录的组 ID(GID),而不是创建文件用户的主组 ID。setuid 对目录无效果。 | |
| S | 与 s 相同,但 x 标志未被设置。该标志在目录上无意义。 | |
| t | 若出现在 others 三元组中,则设置 sticky bit,同时意味着 x 标志被设置。当目录设置了 sticky bit 时,只有文件所有者、目录所有者或管理员用户才能删除或重命名目录中的文件。 | |
| T | 与 t 相同,但 x 标志未被设置。该标志在目录上无意义。 |
使用 chmod 命令
chmod 命令的语法如下:
chmod [OPTIONS] MODE FILE...
chmod 命令允许你使用符号模式、数字模式或参考文件的方式来更改文件的权限。我们会在本文后面更详细地解释这些模式。该命令可以接受一个或多个以空格分隔的文件和(或)目录作为参数。
该命令支持一小部分选项:
- -c, --changes:仅在实际发生更改时报告。
- -f, --silent, --quiet:抑制大多数错误消息。
- -v, --verbose:为每个处理的文件打印一行诊断信息。
- -R, --recursive:递归更改文件和目录。
- --reference=RFILE:从 RFILE 复制模式,而不是手动指定模式。
- --preserve-root:拒绝在 / 上递归操作。这不是默认行为,因此在脚本中递归更改权限时需显式传入。
只有 root 用户、文件所有者或拥有 sudo 权限的用户才能更改文件的权限。使用 chmod 时要格外小心,尤其是在递归更改权限时。
符号(文本)模式
符号模式使用字母和运算符来指定权限,其语法为:
chmod [OPTIONS] [ugoa…][-+=]perms…[,…] FILE...
第一组标志( [ugoa…] )表示用户类别:
- u:文件所有者。
- g:所属组中的成员用户。
- o:所有其他用户。
- a:所有用户,等同于 ugo。
如果省略用户标志,默认是 a,并且由 umask 设置的权限不会受到影响。
第二组标志( [-+=] )是操作标志,用于定义是要移除、添加还是设置权限:
- -:移除指定的权限。
- +:添加指定的权限。
- =:将当前权限更改为指定的权限。如果 = 符号后未指定任何权限,则移除指定用户类别的所有权限。
权限( perms... )可以使用下列字母中的一个或多个(或零个)来显式设置:r、w、x、X、s 和 t。当需要将权限从某一用户类别复制给另一用户类别时,可使用 u、g、o 中的单个字母。
大写的 X 值得一提。它只在目录上、以及至少在某一用户类别中已经设置了执行位的文件上设置执行权限。你通常会看到它与 -R 配合使用,以避免递归更改时把每个普通文件都变成可执行文件。
当为多个用户类别设置权限( [,…] )时,使用逗号(不带空格)来分隔各个符号模式。
下面是一些在符号模式下使用 chmod 命令的示例:
- 给所属组成员赋予读取文件的权限,但不赋予写和执行权限:
chmod g=r filename - 移除所有用户的执行权限:
chmod a-x filename - 递归移除其他用户的写权限:
chmod -R o-w dirname - 移除除文件所有者外所有用户的读、写、执行权限:
chmod og-rwx filename(同样也可用以下形式实现:chmod og= filename) - 给文件所有者读、写、执行权限,给所属组读权限,给其他用户无权限:
chmod u=rwx,g=r,o= filename - 将文件所有者的权限添加给所属组成员拥有的权限:
chmod g+u filename - 给指定目录添加 sticky bit:
chmod o+t dirname
数字(八进制)模式
在数字模式下,你可以一次性为全部三类用户(所有者、所属组、其他用户)设置权限。其语法为:
chmod [OPTIONS] NUMBER FILE...
NUMBER 通常写成三到四位八进制数字,只使用 0 到 7 的数字。
当使用三位数时,第一位表示文件所有者的权限,第二位表示文件所属组的权限,最后一位表示其他所有用户的权限。
写、读、执行各项权限对应的数值如下:
- r(读)= 4
- w(写)= 2
- x(执行)= 1
- 无权限 = 0
某一用户类别的权限数值,等于该类别各项权限数值之和。
要算出数字模式下的文件权限,只需把各类用户的权限数值相加即可。例如,若要给文件所有者读、写、执行权限,给所属组读和执行权限,给其他用户只给读权限,则应如下计算:
- 所有者:rwx=4+2+1=7
- 所属组:r-x=4+0+1=5
- 其他用户:r--=4+0+0=4
用上面的方法,我们得到数字 754,它代表了所需的权限组合。
若要设置 setuid、setgid 和 sticky bit 标志,请使用四位数。
当使用四位数时,第一位数字的含义如下:
- setuid=4
- setgid=2
- sticky=1
- 无更改 = 0
后面三位数字的含义与三位数时相同。
GNU 版的 chmod 接受一到四位八进制数字组成的普通数字模式。前导零是可选的,因此 0755 与 755 等价。五位及以上的数字模式在目录上有特殊行为。例如,chmod 00755 dirname 会显式清除 setuid 和 setgid 位,而 chmod 755 dirname 则会保留它们。
要计算数字模式,也可以使用另一种方法(二进制法),但稍微复杂一些。对大多数用户而言,学会用 4、2、1 来计算数字模式就足够了。
你可以使用 stat 命令以数字形式查看文件的权限:
stat -c "%a" filename
644
下面是一些在数字模式下使用 chmod 命令的示例:
- 给文件所有者读写权限,给所属组成员和其他所有用户只给读权限:
chmod 644 filename - 给文件所有者读、写、执行权限,给所属组成员读和执行权限,给其他所有用户无权限:
chmod 750 filename - 给指定目录读、写、执行权限以及 sticky bit:
chmod 1777 dirname - 递归地给指定目录的文件所有者设置读、写、执行权限,给其他所有用户无权限:
chmod -R 700 dirname
使用参考文件
--reference=ref_file 选项允许你把文件的权限设置为与指定参考文件( ref_file )相同。
chmod --reference=REF_FILE FILE
例如,下面这条命令会把 file1 的权限赋给 file2:
chmod --reference=file1 file2
递归更改文件权限
要对指定目录下的所有文件和目录递归操作,请使用 -R(即 --recursive )选项:
chmod -R MODE DIRECTORY
例如,要把 /var/www 目录下所有文件及子目录的权限改为 755,可以使用:
chmod -R 755 /var/www
递归更改可能会影响不相关的文件,且存在风险。拿不准时,先使用 find ... -print 进行测试。若要进行更精细的递归控制(例如为文件和目录分别设置不同权限),可参考 chmod 递归 相关指南。
操作符号链接
符号链接始终拥有 777 权限,并且 chmod 系统调用无法更改它们。
当你把一个符号链接传给 chmod 时,命令会更改该链接所指向文件的权限:
chmod 755 symlink
有一种情况会导致操作失败并报错 “cannot access 'symlink': Permission denied”。大多数发行版通过 /proc/sys/fs/protected_symlinks 来保护符号链接,其中 1 表示启用,0 表示禁用。在保护开启时,内核会拒绝跟随位于 sticky 且全局可写的目录(如 /tmp )中的链接,当该链接既不属于你、也不属于目录所有者时尤为如此。应直接对目标路径运行 chmod,而不要关闭该保护。
批量更改文件权限
有时你需要批量更改文件和目录的权限。最常见的场景是把网站的文件权限递归地修改为 644(文件)和 755(目录)。
使用数字模式:
find /var/www/my_website -type d -exec chmod 755 {} \;
find /var/www/my_website -type f -exec chmod 644 {} \;
使用符号模式:
find /var/www/my_website -type d -exec chmod u=rwx,go=rx {} \;
find /var/www/my_website -type f -exec chmod u=rw,go=r {} \;
find 命令会搜索 /var/www/my_website 下的文件和目录,并把找到的每一项传给 chmod 命令来设置权限。
常用 chmod 权限数值
有些 chmod 数值非常常用,值得了解它们在实际中的含义。
chmod 644
chmod 644 将权限设为 rw-r--r--:所有者可读写,而所属组和其他用户只有只读权限。这是大多数普通文件和 Web 内容的标准权限。
chmod 644 file
chmod 755
chmod 755 将权限设为 rwxr-xr-x:所有者拥有完整权限(读、写、执行),而所属组和其他用户可读和执行。适用于目录以及应当公开访问的脚本。
chmod 755 dir
chmod 700
chmod 700 将权限设为 rwx------:所有者拥有完整权限,其他任何人都没有任何权限。适用于私有脚本、配置目录,或任何仅限所有者访问的资源。
chmod 700 file
chmod 600
chmod 600 将权限设为 rw-------:只有所有者可以读写,其他任何人都无法访问。适用于敏感文件,例如私钥( ~/.ssh/id_rsa )或存储密码的文件。
chmod 600 file
chmod +x
chmod +x 为未被当前 umask 过滤的用户类别添加执行权限。在常见的 022 umask 下,它会影响所有者、所属组和其他用户,但不改变它们的读或写权限。
chmod +x script.sh
若要确保三类用户都获得执行权限、不受 umask 影响,请显式指定 a:
chmod a+x script.sh
快速参考
如需可打印的快速参考,可查看 chmod 速查表。
| 选项 / 模式 | 说明 |
|---|---|
| chmod u+x file | 为所有者添加执行权限 |
| chmod go-w file | 移除所属组和其他用户的写权限 |
| chmod 644 file | 所有者读写;所属组和其他用户只读 |
| chmod 755 file | 所有者完整权限;所属组和其他用户读和执行 |
| chmod 700 file | 所有者完整权限;所属组和其他用户无权限 |
| chmod 777 file | 所有人都有完整权限(谨慎使用) |
| chmod -R MODE dir | 递归应用权限 |
| chmod --reference=f1 f2 | 从 f1 复制权限到 f2 |
| stat -c "%a" file | 以数字形式查看权限 |
故障排查
“Permission denied”(权限被拒绝):你没有权限更改文件的权限。请运行 sudo chmod ... 或切换到文件所有者。
“No such file or directory”(没有该文件或目录):路径不正确或文件不存在。用 ls 核实,使用绝对路径,或使用 Tab 键自动补全。
“Operation not permitted”(操作不被允许),即使使用了 sudo:常见原因包括不可变(immutable)或仅追加(append-only)属性、不支持按文件 Unix 权限模式的文件系统,或 SELinux/AppArmor 策略限制。可用 lsattr file 检查属性,用 findmnt -T file 确认文件系统和挂载选项,并在更改设置前查看安全日志。只读挂载通常报 “Read-only file system”;noexec 会阻止执行,但不影响 chmod 更改执行位。
更改未作用于符号链接:对符号链接执行 chmod 影响的是目标文件,而非链接本身。如果链接位于 sticky 且全局可写的目录(如 /tmp )中,且属于另一个用户,/proc/sys/fs/protected_symlinks 会阻止该操作。应直接对目标文件运行 chmod。
“Invalid mode”(无效模式)错误(如 “invalid mode: 'abc'”):符号或数字模式中存在拼写错误。数字模式只能使用 0 到 7 的八进制数字。可使用 chmod --verbose 查看应用了哪些更改,并在事后用 ls -l 核实。
常见问题(FAQ)
chmod 644 与 chmod 755 有什么区别? 644 给所有者读写权限,而所属组和其他用户只有只读权限,是 Web 文件的标准权限。755 为所有人添加了执行权限,因此成为目录和可执行脚本的标准权限。关于常用数值的完整说明,可参考 chmod 777 相关指南。
chmod 755 是什么意思? chmod 755 将权限设为 rwxr-xr-x。所有者可读、写、执行,而所属组和其他用户只能读和执行。这是目录和可执行脚本的常见设置。
chmod 644 是什么意思? chmod 644 将权限设为 rw-r--r--。所有者可读写文件,而所属组和其他用户只能读取。它是大多数普通文件和 Web 服务器内容的标准权限。
chmod 700 是什么意思? chmod 700 将权限设为 rwx------。所有者拥有完整访问权限,其他任何用户都无法读、写或执行该文件。适用于私有脚本、含敏感数据的目录,或像 ~/.ssh 这样的 SSH 密钥目录。
chmod 600 是什么意思? chmod 600 将权限设为 rw-------。只有所有者可以读写文件,其他人无任何访问权限。它是私钥( ~/.ssh/id_rsa )和存储凭据文件的标准权限。
如何只对文件(而非目录)递归应用 chmod? 在传给 chmod 之前,先用 find 按类型过滤。例如:find /path -type f -exec chmod 644 {} \; 只会对文件设置权限。完整指南可参考 chmod 递归 相关内容。
chmod +x 有什么作用? 它为未被当前 umask 过滤的用户类别添加执行权限。在常见的 022 umask 下,它会影响所有者、所属组和其他用户。使用 chmod a+x script.sh 可为三类用户授予执行权限,不受 umask 影响。
能在同一条 chmod 命令中同时使用字母和数字吗? 不能。符号模式(字母)和数字模式(八进制数字)是两种独立的方法,在单次 chmod 调用中只能使用其中一种。
如果对文件运行 chmod 777 会怎样? 它会授予系统上所有人读、写、执行权限。除测试环境外很少合适,请勿在生产文件和 Web 服务器目录上使用。
总结
chmod 命令让你可以精确控制谁能在 Linux 系统上读、写、执行文件和目录。若要深入了解权限如何与所有权相互作用,可参考 chown 与 chgrp 命令。