chmod 是 change mode 的缩写,是 Linux/Unix 及类 Unix 系统中修改文件/目录访问权限的核心命令,是系统权限管理、安全配置的基础工具。它完全兼容 POSIX 标准,支持符号模式(灵活增量修改)和八进制数字模式(精准全量设置)两种权限配置方式,可实现对所有者、用户组、其他用户的精细化权限控制,同时支持 SUID、SGID、粘滞位三类特殊权限的配置。
一、前置知识:Linux 文件权限核心体系
在使用 chmod 前,必须先理解 Linux 的 UGO 权限模型,这是 chmod 命令的核心底层逻辑。
1.1 权限位的基础结构
Linux 中每个文件/目录的权限都由 10 个字符构成,通过 ls -l 命令可查看,示例如下:
-rwxr-xr-- 1 user group 0 May 7 10:00 test.sh
10个字符的拆解规则:
- • 文件类型:
- 普通文件、d 目录、l 软链接、c 字符设备、b 块设备、s 套接字、p 管道文件 - •
u(user/所有者):文件/目录的创建者或指定拥有者 - •
g(group/所属组):文件归属的用户组,同组用户共享权限 - •
o(other/其他用户):除所有者、所属组外的所有用户 - •
a(all/所有用户):u+g+o 的合集,符号模式中不指定用户时默认值为 a
1.2 基础权限 rwx 的核心含义
rwx 三个权限位对普通文件和目录的作用完全不同,这是新手最容易踩坑的核心点,详细对比如下:
| | | |
|---|
r | | 允许查看、读取文件内容(cat、more、head等) | 允许列出目录内的文件列表(ls),必须配合x权限才能生效 |
w | | 允许修改、新增、删除文件内容(vim、echo、重定向等) | 允许在目录内创建/删除/重命名/移动文件/子目录,必须配合x权限才能生效 |
x | | 允许运行二进制可执行文件、脚本(Shell、Python等) | 允许进入目录(cd命令),是目录所有操作的基础权限 |
关键记忆点:目录的 x 是「准入权限」,没有 x 权限,r 和 w 权限几乎完全失效。
二、chmod 命令基础语法与常用选项
2.1 标准语法
chmod [选项] 权限模式 文件/目录路径
- •
权限模式:核心参数,支持八进制数字模式和符号模式两种写法,不可同时混用 - •
文件/目录路径:支持单个/多个目标,支持通配符(*、? 等)
2.2 核心常用选项
所有选项均兼容 GNU 标准,常用选项详细说明如下:
| | | |
|---|
--recursive | -R | | chmod -R 755 /var/www/html |
--verbose | -v | 详细输出每个文件的权限变更情况(无论是否修改成功) | chmod -v u+x test.sh |
--changes | -c | 仅输出实际发生权限变更的文件信息,比 -v 更精简 | chmod -c 644 *.txt |
--silent/--quiet | -f | 静默模式,忽略大部分错误信息(如权限不足、文件不存在) | chmod -f -R 755 /data |
--reference | | 以参考文件的权限为模板,同步设置目标文件/目录的权限 | chmod --reference=ref.txt target.txt |
--help | | | chmod --help |
--version | | | chmod --version |
注意:-R 递归选项不会跟随软链接,仅修改软链接指向的目标文件/目录,不会修改软链接本身的权限。
三、核心权限配置模式(全量覆盖)
chmod 提供两种权限配置模式,适用于不同场景,是命令的核心内容。
3.1 八进制数字模式(最常用,绝对权限设置)
八进制模式通过 3~4 位数字,一次性全量设置文件/目录的权限,是生产环境、脚本编写中最常用的方式,特点是精准、简洁、无歧义。
3.1.1 权限与数字的映射规则
基础权限与八进制数字的固定映射,不可修改:
每一类用户(u/g/o)的权限值 = 对应权限位的数字之和,例如:
3.1.2 数字格式规范
- • 3位数字格式:
[u权限值][g权限值][o权限值],用于设置基础权限,最常用 - • 4位数字格式:
[特殊权限值][u权限值][g权限值][o权限值],用于同时设置特殊权限+基础权限(特殊权限详解见第四部分)
3.1.3 常见权限值详解与适用场景
| | | |
|---|
| rw------- | | 包含敏感信息的配置文件、密钥文件(如数据库配置、SSH私钥) |
| rw-r--r-- | | 普通静态文件、网站静态资源、文档、配置文件(非敏感) |
| rwx------ | | |
| rwxr-xr-x | | |
| rwxrwxr-x | | |
| rwxrwxrwx | | 仅临时测试使用,生产环境严禁使用,存在极高安全风险 |
3.1.4 常用示例
# 给脚本设置所有者可读写执行,其他用户可读可执行chmod 755 test.sh# 给配置文件设置仅所有者可读写,其他用户无权限chmod 600 /etc/mysql/my.cnf# 给网站静态文件设置全局只读,所有者可写chmod 644 /var/www/html/*.html# 递归设置目录权限为755chmod -R 755 /var/www/html
3.2 符号模式(灵活增量修改)
符号模式通过「用户主体+操作符+权限位」的组合,实现对权限的增量修改,无需覆盖原有全部权限,适合精细化调整、单次多规则修改场景。
3.2.1 符号模式四要素
标准格式:[ugoa][+-=][rwxXst],支持多组规则用逗号分隔。
1. 用户主体(Who):指定要修改的用户范围
2. 操作符(Operator):指定权限的修改方式
3. 权限位(Permission):指定要操作的权限类型
| | |
|---|
r | | |
w | | |
x | | |
X | | 仅给目录添加执行权限,不给普通文件添加(递归修改神器,见进阶用法) |
s | | |
t | | |
3.2.2 常用示例
增量添加权限
# 给所有者添加执行权限chmod u+x test.sh# 给所属组和其他用户同时添加读权限chmod go+r file.txt# 给所有用户添加执行权限chmod a+x script.sh# 等价于(不写主体默认a)chmod +x script.sh
精准移除权限
# 给所属组移除写权限chmod g-w file.txt# 给其他用户移除读写执行所有权限chmod o-rwx file.txt# 给所有用户移除执行权限chmod a-x *.txt
全量覆盖权限
# 设置其他用户只有读权限,覆盖原有所有权限chmod o=r file.txt# 设置所有者读写执行,所属组可读执行,其他用户无权限chmod u=rwx,g=rx,o= test.sh# 设置所有用户只读权限chmod a=r *.conf
多规则组合修改
# 给所有者加执行权限,给所属组移除写权限,给其他用户设为只读chmod u+x,g-w,o=r file.txt
四、特殊权限位(SUID/SGID/粘滞位)进阶详解
除了基础的 rwx 权限,Linux 还提供了三个特殊权限位,用于实现更复杂的权限控制场景,占据 4 位八进制数字的最高位,也可通过符号模式设置。
4.1 SUID(Set User ID)
核心作用
仅对二进制可执行文件生效,对目录、脚本文件无实际意义。用户执行该文件时,进程的有效用户ID(EUID)会临时变为文件的所有者,而非执行者本人,实现临时权限提升。
典型场景
系统原生的 /usr/bin/passwd 命令,权限为 -rwsr-xr-x。普通用户执行 passwd 时,会临时获得 root 权限,从而修改只有 root 可写的 /etc/shadow 密码文件。
设置与移除方法
# 符号模式设置chmod u+s /path/to/binary_file# 符号模式移除chmod u-s /path/to/binary_file# 八进制模式设置(最高位加4)chmod 4755 /path/to/binary_file# 八进制模式移除(最高位设为0)chmod 0755 /path/to/binary_file
关键注意事项与安全红线
- 1. 生效限制:仅对二进制可执行文件生效,对 Shell/Python 等脚本文件完全无效;对目录设置无意义。
- 2. 权限显示:所有者的 x 位会变为
s(文件本身有x权限,生效状态);若变为大写 S,说明文件无x权限,SUID 已设置但完全无效。 - 3. 安全风险:SUID 存在极高的权限逃逸风险,严禁给 bash、vim、rm 等系统命令设置 SUID,否则普通用户可直接提权至 root,导致系统完全失控。非必要场景绝对不要使用。
4.2 SGID(Set Group ID)
核心作用
SGID 可作用于二进制可执行文件和目录,其中对目录的设置是生产环境最常用的场景:
- 1. 对可执行文件:执行时,进程的有效用户组ID(EGID)会临时变为文件的所属组,类似 SUID。
- 2. 对目录:核心用途!目录下新建的文件/子目录,会自动继承该目录的所属组,而非创建者的默认主组,完美解决团队协作中文件归属不一致的问题。
典型场景
团队共享开发目录,设置 SGID 后,所有成员在目录内创建的文件都归属项目组,同组成员可正常编辑,无需频繁修改文件所属组。
设置与移除方法
# 符号模式设置chmod g+s /path/to/dir# 符号模式移除chmod g-s /path/to/dir# 八进制模式设置(最高位加2)chmod 2755 /path/to/dir# 八进制模式移除chmod 0755 /path/to/dir
关键注意事项
- 1. 权限显示:所属组的 x 位会变为
s(目录/文件有x权限,生效状态);若变为大写 S,说明无x权限,SGID 无效。 - 2. 继承规则:SGID 对目录内已存在的文件/子目录无效,仅对设置后新建的内容生效,需手动修改已有文件的所属组。
- 3. 安全性:对目录设置 SGID 是安全且常用的协作方案,远比对文件设置的风险低。
4.3 Sticky Bit(粘滞位)
核心作用
仅对目录生效,对文件无意义。即使目录对所有用户开放了写权限,目录内的文件/子目录,也只有文件所有者、目录所有者、root 用户有权删除/移动/重命名,其他用户即使有w权限,也无法操作他人的文件。
典型场景
系统的 /tmp 目录,权限为 drwxrwxrwt,所有用户都可在目录内创建文件,但只能删除自己的文件,防止用户恶意删除/修改他人的临时文件。
设置与移除方法
# 符号模式设置chmod o+t /path/to/public_dir# 符号模式移除chmod o-t /path/to/public_dir# 八进制模式设置(最高位加1)chmod 1777 /path/to/public_dir# 八进制模式移除chmod 0777 /path/to/public_dir
关键注意事项
- 1. 权限显示:其他用户的 x 位会变为
t(目录有x权限,生效状态);若变为大写 T,说明目录无x权限,粘滞位无效。 - 2. 适用场景:公共上传目录、团队共享目录、多用户可写的临时目录,是防止误删/恶意删除的核心方案。
特殊权限速查表
组合设置:可同时设置多个特殊权限,八进制值相加即可,例如同时设置 SUID+SGID,最高位为 4+2=6,权限值为 6755。
五、进阶用法与实战技巧
5.1 大写 X 权限:递归修改的神器
核心作用
X 权限是 x 权限的特殊变体,仅对目录和「已有至少一个x权限的文件」生效,不会给普通无执行权限的文件添加x权限。完美解决 chmod -R 755 递归修改时,给所有静态文件都加上执行权限的安全坑。
典型示例
# 递归给网站目录的所有子目录添加执行权限,普通文件保持不变chmod -R a+X /var/www/html# 精准设置:所有者读写执行,组和其他用户读+目录准入,文件无执行权限chmod -R u=rwx,go=rX /var/www/html
5.2 参考文件权限批量同步
通过 --reference 选项,可直接以参考文件的权限为模板,批量同步目标文件的权限,无需手动计算权限值,适合批量标准化配置场景。
# 让 target.txt 的权限和 ref.txt 完全一致chmod --reference=ref.txt target.txt# 批量同步nginx配置文件权限,以主配置文件为模板chmod --reference=/etc/nginx/nginx.conf /etc/nginx/conf.d/*.conf# 递归同步整个目录的权限,以参考目录为模板chmod -R --reference=/var/www/model_dir /var/www/target_dir
5.3 批量修改权限的正确姿势(避坑)
生产环境中,严禁直接使用 chmod -R 755 目录,这会给所有静态文件(html、图片、文档)都加上执行权限,存在严重安全风险。正确做法是通过 find 命令,分别对目录和文件设置不同权限。
# 1. 批量修改所有目录权限为755find /var/www/html -type d -exec chmod 755 {} \;# 2. 批量修改所有文件权限为644find /var/www/html -type f -exec chmod 644 {} \;# 高效优化版(xargs减少进程创建)find /var/www/html -type d -print0 | xargs -0 chmod 755find /var/www/html -type f -print0 | xargs -0 chmod 644
5.4 软链接的权限处理规则
- 1. 核心规则:chmod 命令永远不会修改软链接本身的权限,只会作用于软链接指向的目标文件/目录。
- 2. 底层逻辑:Linux 系统中,软链接本身的权限始终是 777,但其实际访问权限完全由目标文件/目录决定,修改软链接本身的权限无任何意义。
- 3. 递归规则:
chmod -R 不会跟随软链接进入子目录,避免循环链接导致的权限污染。
六、常见坑与安全红线(生产环境必看)
6.1 严禁滥用 777 权限
777 权限意味着所有用户都拥有读写执行权限,相当于系统门户大开,恶意用户可直接修改文件、植入恶意代码、执行非法程序,极易导致系统被入侵、数据泄露。
- • 替代方案:通过用户组权限控制,比如团队协作使用 775,公开访问使用 755/644,绝对不要用 777。
- • 禁用场景:系统关键目录、网站根目录、可执行脚本、配置文件,永久禁止设置 777 权限。
6.2 递归修改的权限污染
- • 禁止无差别递归修改权限,尤其是
chmod -R 777 /、chmod -R 777 * 这类操作,会直接破坏系统文件权限,导致命令无法执行、系统无法启动。 - • 递归修改前必须确认目标范围,优先使用
find 分开处理目录和文件,或使用 X 权限精准控制。
6.3 系统关键目录权限禁忌
以下系统核心目录/文件,严禁随意修改权限,错误的权限修改会直接导致系统崩溃、无法登录、远程连接失败:
- •
/ 根目录、/root root家目录、/etc 系统配置目录 - •
/bin、/sbin、/usr/bin、/usr/sbin 系统命令目录 - •
/etc/shadow、/etc/passwd 用户密码文件,必须保持 600/644 权限 - •
/etc/ssh/sshd_config SSH 配置文件,权限错误会导致远程登录失败
6.4 权限修改的身份限制
- • 只有 root 超级用户 和 文件/目录的所有者,才有权限修改文件/目录的权限,其他用户即使有写权限,也无法修改权限。
- • root 用户可以无视任何权限限制,修改系统中所有文件的权限,操作需极度谨慎。
七、配套相关命令(权限管理完整体系)
7.1 权限查看命令
| | |
|---|
ls -l | | ls -l test.sh |
ls -ld | | ls -ld /var/www/html |
stat | | stat -c "%a %n" test.sh |
7.2 配套权限管理命令
| | |
|---|
umask | 设置新建文件/目录的默认权限掩码,决定新文件的初始权限 | chmod 是手动修改已有权限,umask 是控制新建文件的默认权限 |
chown | | 权限控制的前提是正确的用户/组归属,与 chmod 配合使用 |
chgrp | | |
getfacl/setfacl | | 突破 UGO 三类用户的限制,实现对单个用户/单个组的精细化权限控制,是 chmod 的进阶补充 |
八、生产环境实战案例
8.1 网站目录标准权限配置
场景:Nginx/Apache 网站根目录 /var/www/html,要求:
- • 所有者 root 有完全权限,网站运行用户 www-data 有读权限
- • 目录可进入、可列出,静态文件只读,禁止执行权限
# 1. 设置统一的所有者和所属组chown -R root:www-data /var/www/html# 2. 批量设置目录权限为755(所有者全权限,其他用户可读+进入)find /var/www/html -type d -exec chmod 755 {} \;# 3. 批量设置普通文件权限为644(所有者可写,全局只读)find /var/www/html -type f -exec chmod 644 {} \;# 4. 给上传目录设置可写权限,同时设置SGID保证文件归属chmod 2775 /var/www/html/uploadchown root:www-data /var/www/html/upload
8.2 团队共享目录配置
场景:/data/share 团队协作目录,要求:
- • 新建文件自动继承 team 组,同组用户可正常编辑
# 1. 创建用户组(若不存在)groupadd team# 2. 创建目录并设置归属mkdir -p /data/sharechown root:team /data/share# 3. 设置权限2770:SGID+所有者/组全权限,其他用户无权限chmod 2770 /data/share
8.3 公共上传目录配置
场景:/data/public 公共文件服务器目录,要求:
- • 用户只能删除/修改自己的文件,无法操作他人文件
# 1. 创建目录mkdir -p /data/public# 2. 设置权限1777:粘滞位+所有用户读写执行权限chmod 1777 /data/public
8.4 敏感配置文件安全加固
场景:数据库配置文件、SSH 私钥文件,要求:
# SSH私钥文件加固chmod 600 /root/.ssh/id_rsachown root:root /root/.ssh/id_rsa# 数据库配置文件加固chmod 600 /etc/mysql/my.cnfchown mysql:mysql /etc/mysql/my.cnf