第 5 章 · 02 `chmod`:符号式与八进制


文档摘要

第 5 章 · 02 :符号式与八进制 本节摘要:第 01 节你学会了读权限,本节教你「改权限」。 同时支持两套写法:符号式( 、 、 ,像在做加减法,直观、增量)和八进制( 、 ,像在画一张完整的新权限表,精确、整体覆盖)。这两套写法不是冗余,而是面向两种截然不同的场景——「只想给某个组加个权限」用符号式,「要把权限整体设成某个标准值」用八进制。本节要把两套写法的语法、换算、 递归的陷阱都讲透,让你以后看到 或 都能脱口而出它在干什么。 内容来源:原项目「Linux 命令大全」 ,精选并套用体系化模板。 学习目标 阅读完本节,你应当能够: 用符号式 调整权限: 、 、 、 ,理解 / / 的差别。 用八进制 设置权限: 、 、 ,能在脑内秒换算成 。

第 5 章 · 02 chmod:符号式与八进制

本节摘要:第 01 节你学会了读权限,本节教你「改权限」。chmod 同时支持两套写法:符号式(u+xg-wo=r-x,像在做加减法,直观、增量)和八进制(755644,像在画一张完整的新权限表,精确、整体覆盖)。这两套写法不是冗余,而是面向两种截然不同的场景——「只想给某个组加个权限」用符号式,「要把权限整体设成某个标准值」用八进制。本节要把两套写法的语法、换算、-R 递归的陷阱都讲透,让你以后看到 chmod 755 filechmod u+x script.sh 都能脱口而出它在干什么。

内容来源:原项目「Linux 命令大全」command/chmod.md,精选并套用体系化模板。

学习目标

阅读完本节,你应当能够:

  1. 用符号式 chmod 调整权限:u+xg-wo=r-xa+r,理解 +/-/= 的差别。
  2. 用八进制 chmod 设置权限:755644600,能在脑内秒换算成 rwxr-xr-x
  3. 区分两种写法的适用场景:增量微调用符号式,整体覆盖用八进制。
  4. 说清 -R 递归的陷阱:它会把目录的 x 一起改掉,导致文件被错误加上执行位。
  5. X(大写)在递归时只给目录加执行位,不给普通文件加。

一、设计动机:为什么有两套写法

设想两种常见需求:

  • 需求 A:你写了个脚本 deploy.sh,现在只想给自己加上执行权限,其他权限保持不变。
  • 需求 B:你下载了个 web 项目,要把所有文件权限重置成 644、所有目录重置成 755

需求 A 的特点是「只动一个位,其他位保持」——你不想关心现在的权限是什么,只想「加上 ux」。需求 B 的特点是「整体设成一个确定值」——你不关心原来是多少,只要结果是 644/755

chmod 的两套写法正好对应这两种心智:

  • 符号式:像做加减法。u+x 表示「在属主权限上加上 x」,其他位不动。适合增量微调。
  • 八进制:像填一张表。755 表示「属主 rwx、属组 r-x、其他 r-x」,不管原来是什么,直接覆盖成这个值。适合整体重置。

关键概念:符号式是「增量」,八进制是「整体覆盖」——这是两套写法最本质的区别。记错这个会导致严重事故:本来只想加个 x,结果用 chmod 755 把属主的 w 给弄没了;或者本来想整体重置,结果用 u+x 只改了一位其他没动。

二、高频组合与实战

1. 符号式:增、减、设

符号式的语法骨架是 「对象 操作符 权限」,可以串多个,用逗号分隔。

对象: u(属主) g(属组) o(其他) a(全部, 等同 ugo) 操作符: +(加) -(减) =(设为, 清掉未提到的) 权限: r(读) w(写) x(执行) X(目录或已有 x 的文件才加 x) s(特殊位) t(粘滞位)
chmod u+x deploy.sh # 给属主加执行权限 chmod g-w report.txt # 去掉属组的写权限 chmod o=r notes.txt # 其他设为只读(= 会清掉 w 和 x) chmod a+r public.html # 所有人加读权限 chmod u=rwx,g=rx,o= app.py # 属主 rwx, 属组 r-x, 其他无任何权限(注意 o= 后为空)

三种操作符的差别务必分清:

  • +:在现有权限基础上叠加,不触碰未提到的位。
  • -:在现有权限基础上移除,不触碰未提到的位。
  • =:直接设成指定值,未提到的位一律清零o=r-x 会把 w 清掉,o=(空)会把该组所有权限清零。

💡 技巧:=+/- 更安全,因为它「确定」。生产环境改权限时,推荐用 = 而非 +/-,避免「我以为现在的权限是 X」这类假设出错。

2. 八进制:整体覆盖

八进制写法就是第 01 节讲的换算:r=4、w=2、x=1,每组的权限相加成一个 0-7 的数字,三组拼成一个三位数。

chmod 755 script.sh # rwxr-xr-x: 脚本/目录的常见权限 chmod 644 notes.txt # rw-r--r--: 普通文件的常见权限 chmod 600 secret.key # rw-------: 私钥等敏感文件 chmod 700 ~/.ssh # rwx------: 只有自己能进 chmod 777 public_share # rwxrwxrwx: 谁都能改(危险, 慎用)

⚠️ 注意:chmod 777 几乎永远是坏主意。它意味着「任何人都能改这个文件」,攻击者可以往里塞恶意代码。临时调试时用 777 还情有可原,正式环境绝不该出现

常见的「权限惯例值」你应当背下来:

八进制 字符 含义 典型场景
755 rwxr-xr-x 自己可写、他人只读可执行 目录、可执行脚本
644 rw-r--r-- 自己可改、他人只读 普通配置/文档
700 rwx------ 只有自己 私人目录(~/.ssh)
600 rw------- 只有自己 私钥、密码文件
640 rw-r----- 自己可改、组只读、其他无 组内共享但对外保密

3. 多对象同时改(符号式的高级用法)

chmod u+x,g+w,o-w file # 三组同时改, 逗号分隔 chmod ug+w,o-w file # u 和 g 合并写: 都加 w, o 去掉 w chmod a=r,ugo+x file # 先全部设为 r, 再给所有组加 x

4. 用 --reference 参照另一个文件

chmod --reference=template.conf new.conf # 把 new.conf 的权限设成和 template.conf 一样

这在批量对齐权限时很有用——不用记模板的八进制是多少,直接「照着抄」。

5. 脚本部署场景:文件与目录分别设权限

这是 web 部署里最经典的一段「权限收尾」脚本:

# 部署完代码后, 把权限统一到标准值 find /var/www/mysite -type d -exec chmod 755 {} \; # 所有目录: 755 find /var/www/mysite -type f -exec chmod 644 {} \; # 所有普通文件: 644 # 再单独把可执行脚本和敏感配置挑出来调整 find /var/www/mysite -name '*.sh' -exec chmod 755 {} \; # 脚本: 加执行位 find /var/www/mysite -name '*.key' -exec chmod 600 {} \; # 私钥: 只属主可读 find /var/www/mysite -name '*.env' -exec chmod 640 {} \; # 环境配置: 属组只读

这套流程体现了一个重要原则:权限管理是「分层渐进」的——先把所有东西设成「安全默认」(文件 644、目录 755),再对特殊文件单独调整。不要试图一条命令搞定所有情况。

6. 数字权限与「三组」的对应心法

把 755/644 这种数字拆回三组,训练自己的心算:

755 → 7 5 5 → rwx r-x r-x → 属主全权, 属组和其他只读可执行 644 → 6 4 4 → rw- r-- r-- → 属主读写, 属组和其他只读 600 → 6 0 0 → rw- --- --- → 只有属主能读写 700 → 7 0 0 → rwx --- --- → 只有属主能进(目录常用) 1777→ 1 7 7 7 → 特殊位1(粘滞) + rwx rwx rwx → /tmp 的权限

💡 技巧:看到四位数字(如 4755)时,第一位是特殊位,后三位才是常规权限。日常三位的 755/644 用得最多,四位主要出现在 /tmp(1777)、/usr/bin/passwd(4755,带 suid)等系统文件上。

三、踩坑与排错

坑 1:chmod -R 把目录的 x 加到了文件上

-R 是递归,看似无害,实则暗坑。最大的坑是:

chmod -R 755 myproject/ # 把目录和所有文件都设成 755

听起来没问题,但普通文件被设成 755(rwxr-xr-x)意味着所有文件都带执行位,而执行位对配置文件、日志、图片来说是毫无意义且危险的——别人下载你的 config.yml 不会去执行它,但带 x 会让一些工具误判。

正确做法是目录和文件分开:

# 找出所有目录设 755, 所有普通文件设 644 find myproject/ -type d -exec chmod 755 {} \; find myproject/ -type f -exec chmod 644 {} \;

💡 技巧:用 X(大写)更省事——它表示「只对目录、或已经拥有执行位的文件x」。所以递归加执行位时用 chmod -R a+X *,普通文件(原本没有 x)不会被错误加上,而目录会得到 x

坑 2:符号式和八进制混用导致权限意外丢失

# 假设文件现在是 rwxrwxr-x (775) chmod u+x file # 加 x, 但 u 已经有 x, 结果还是 775(无变化) chmod 755 file # 直接覆盖成 755, 属组的 w 没了! 变成 rwxr-xr-x

新手以为「我只是改 u,怎么 gw 没了?」——因为你用了八进制,八进制永远覆盖,不保留任何旧权限。如果你想「只动 u」,必须用符号式 u+x,不能用 755

坑 3:误把 chmod 0755 当成特殊写法

你会在网上看到 chmod 0755 file,前面那个 0 让人困惑。其实前面的 0 是「特殊权限位」(suid/sgid/sticky)的占位,0755755 在大多数场景下等价(特殊位都是 0)。但如果出现 4755(4 是 suid 位)、2755(2 是 sgid 位)、1755(1 是 sticky 位),就要小心了——这些特殊位会让程序以「文件属主身份」运行(典型的如 passwd 命令是 4755)。本节不展开,知道含义即可。

坑 4:对符号链接 chmod 改的是目标

ln -s target.txt link.txt chmod 600 link.txt # 你以为改的是 link.txt, 实际改的是 target.txt!

大多数 Linux 实现 chmod跟随符号链接,改的是目标文件。要改链接本身,需要 chmod -h(并非所有系统支持)。实务建议:不要对符号链接用 chmod,直接改目标文件,避免混淆

坑 5:o=(空)和 o-rwx 不是同一回事

chmod o= file # 把其他权限设为「空」(直接覆盖成 ---) chmod o-rwx file # 从现有权限里减去 rwx(如果原本没某位, 减了也没事)

多数时候结果一样,但如果其他组原本就有特殊位(如 sticky),o= 会清掉,o-rwx 不会。生产环境用 = 更彻底,用 - 更保守

坑 6:误以为 chmod 能改 ACL 或扩展属性

chmod 只能改传统的 9 位权限(加 3 位特殊位)。但现代 Linux 还有 ACL(Access Control List,getfacl/setfacl)和扩展属性(chattr/lsattr),它们能做更细粒度的控制:

# ACL: 让某个特定用户(而不只是属主/属组/其他)有权限 setfacl -m u:alice:rw file # 给 alice 单独加 rw getfacl file # 查看 ACL # 扩展属性: 比权限位更强的保护 sudo chattr +i critical.conf # +i 设 immutable, 连 root 都不能删/改! lsattr critical.conf # 查看

chattr +i(immutable)特别有用——即使 root 也无法删除或修改该文件,直到 chattr -i 解除。这超出了 chmod 的能力范围,常用于保护关键系统文件。遇到「明明是 root 却删不掉文件」,先 lsattr 看看是不是被设了 immutable

💡 技巧:chmod 之上还有 ACL,ACL 之上还有 chattr——三层权限体系层层叠加。日常用 chmod 足够,但排查「权限诡异」时要想到后两层。

坑 7:chmod 改了权限,但 web 服务还是访问不了

新手常误以为「改了 chmod 就万事大吉」,结果 web 服务器(以 www-data 用户运行)还是访问不了文件。根因是:权限只是「身份确认后允不允许」,身份本身(chown/chgrp)没对。比如文件是 alice:alice,你 chmod 640(属组只读),但 www-data 既不是 alice 也不是 alice 组成员,就只能用「其他」那组权限(---),自然访问不了。

排查思路:ls -l 看属主属组 → 确认服务运行用户 → 检查该用户属于哪个组 → 决定它用 u/g/o 哪组权限。权限和身份要一起考虑,见第 04 节。

坑 8:在容器/CI 里 chmod 不生效——挂载遮盖

# docker-compose.yml 里挂了 volume volumes: - ./config:/app/config # 容器内 chmod /app/config/app.yml, 但 host 上权限没变?

bind mount(绑定挂载)时,容器内的权限改的就是 host 上的文件——但如果你在 host 上 ls -l 看到的属主是容器内的 UID(如 1000),会以为是「没生效」。实际上权限改了,只是 UID 显示对不上(host 上没有这个用户名)。容器权限问题要先理清 UID 映射,单纯 chmod 解决不了根本问题。这是第 7 章(挂载)和容器话题的交叉点。

四、决策流程:符号式还是八进制

把前面的原则整理成一个简单决策流程:

要改权限? │ ├─ 只动某一两位, 其他保持 → 符号式 (chmod u+x, g-w) │ ├─ 整体重置成标准值 → 八进制 (chmod 755, 644) │ ├─ 批量对齐到参照文件 → --reference (chmod --reference=t.txt *) │ ├─ 递归处理整棵树 │ ├─ 文件和目录权限一样 → 用 X (chmod -R a+X *) 只给目录加 x │ └─ 文件和目录权限不同 → find 分开处理 (find -type d/f) │ └─ 脚本里保护敏感产物 → 先 umask, 而不是事后 chmod

💡 技巧:如果不确定用哪种,问自己「我知道目标权限的完整八进制吗」——知道就用八进制(更精确),不知道(只关心「加个执行位」这种相对变化)就用符号式。这个二分能覆盖大多数场景。

本节要点回顾

  1. chmod 有两套写法:符号式(u+x,增量)和八进制(755,整体覆盖)——增量用符号、重置用八进制
  2. 符号式三操作符:+(加)、-(减)、=(设为,清掉未提到的)。生产环境优先用 =,更确定
  3. 八进制换算:r=4、w=2、x=1 相加,三组拼成三位数。背熟 755/644/700/600 四个常见值
  4. -R 递归的大坑:会把目录的 x 加到文件上,文件应设 644、目录应设 755,用 find -type d/f 分开处理,或用大写 X 只给目录加 x
  5. 八进制永远覆盖,不要在只想改一位时用八进制——会意外清掉其他位。
  6. 符号链接的 chmod 改的是目标,不要对链接直接 chmod
  7. 0755755 等价(前面 0 是特殊位占位);4755/2755/1755 是带特殊位的权限,慎用。

下一节是本章的另一个核心难点:目录权限的真相。目录的 r/w/x 与文件含义完全不同——r 是「能列出文件名」、w 是「能增删文件」、x 是「能进入」。理解了它,你才能破解「为什么能 ls 却打不开文件」「为什么给目录 w 等于送人删除权」这些反直觉现象。


发布者: 作者: 灏天文库 转发
评论区 (0)
U