第 5 章 · 02 :符号式与八进制 本节摘要:第 01 节你学会了读权限,本节教你「改权限」。 同时支持两套写法:符号式( 、 、 ,像在做加减法,直观、增量)和八进制( 、 ,像在画一张完整的新权限表,精确、整体覆盖)。这两套写法不是冗余,而是面向两种截然不同的场景——「只想给某个组加个权限」用符号式,「要把权限整体设成某个标准值」用八进制。本节要把两套写法的语法、换算、 递归的陷阱都讲透,让你以后看到 或 都能脱口而出它在干什么。 内容来源:原项目「Linux 命令大全」 ,精选并套用体系化模板。 学习目标 阅读完本节,你应当能够: 用符号式 调整权限: 、 、 、 ,理解 / / 的差别。 用八进制 设置权限: 、 、 ,能在脑内秒换算成 。
chmod:符号式与八进制本节摘要:第 01 节你学会了读权限,本节教你「改权限」。
chmod同时支持两套写法:符号式(u+x、g-w、o=r-x,像在做加减法,直观、增量)和八进制(755、644,像在画一张完整的新权限表,精确、整体覆盖)。这两套写法不是冗余,而是面向两种截然不同的场景——「只想给某个组加个权限」用符号式,「要把权限整体设成某个标准值」用八进制。本节要把两套写法的语法、换算、-R递归的陷阱都讲透,让你以后看到chmod 755 file或chmod u+x script.sh都能脱口而出它在干什么。
内容来源:原项目「Linux 命令大全」
command/chmod.md,精选并套用体系化模板。
阅读完本节,你应当能够:
chmod 调整权限:u+x、g-w、o=r-x、a+r,理解 +/-/= 的差别。chmod 设置权限:755、644、600,能在脑内秒换算成 rwxr-xr-x。-R 递归的陷阱:它会把目录的 x 一起改掉,导致文件被错误加上执行位。X(大写)在递归时只给目录加执行位,不给普通文件加。设想两种常见需求:
deploy.sh,现在只想给自己加上执行权限,其他权限保持不变。644、所有目录重置成 755。需求 A 的特点是「只动一个位,其他位保持」——你不想关心现在的权限是什么,只想「加上 u 的 x」。需求 B 的特点是「整体设成一个确定值」——你不关心原来是多少,只要结果是 644/755。
chmod 的两套写法正好对应这两种心智:
u+x 表示「在属主权限上加上 x」,其他位不动。适合增量微调。755 表示「属主 rwx、属组 r-x、其他 r-x」,不管原来是什么,直接覆盖成这个值。适合整体重置。关键概念:符号式是「增量」,八进制是「整体覆盖」——这是两套写法最本质的区别。记错这个会导致严重事故:本来只想加个
x,结果用chmod 755把属主的w给弄没了;或者本来想整体重置,结果用u+x只改了一位其他没动。
符号式的语法骨架是 「对象 操作符 权限」,可以串多个,用逗号分隔。
对象: 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」这类假设出错。
八进制写法就是第 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----- |
自己可改、组只读、其他无 | 组内共享但对外保密 |
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
--reference 参照另一个文件chmod --reference=template.conf new.conf # 把 new.conf 的权限设成和 template.conf 一样
这在批量对齐权限时很有用——不用记模板的八进制是多少,直接「照着抄」。
这是 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),再对特殊文件单独调整。不要试图一条命令搞定所有情况。
把 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)等系统文件上。
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。
# 假设文件现在是 rwxrwxr-x (775) chmod u+x file # 加 x, 但 u 已经有 x, 结果还是 775(无变化) chmod 755 file # 直接覆盖成 755, 属组的 w 没了! 变成 rwxr-xr-x
新手以为「我只是改 u,怎么 g 的 w 没了?」——因为你用了八进制,八进制永远覆盖,不保留任何旧权限。如果你想「只动 u」,必须用符号式 u+x,不能用 755。
chmod 0755 当成特殊写法你会在网上看到 chmod 0755 file,前面那个 0 让人困惑。其实前面的 0 是「特殊权限位」(suid/sgid/sticky)的占位,0755 和 755 在大多数场景下等价(特殊位都是 0)。但如果出现 4755(4 是 suid 位)、2755(2 是 sgid 位)、1755(1 是 sticky 位),就要小心了——这些特殊位会让程序以「文件属主身份」运行(典型的如 passwd 命令是 4755)。本节不展开,知道含义即可。
chmod 改的是目标ln -s target.txt link.txt chmod 600 link.txt # 你以为改的是 link.txt, 实际改的是 target.txt!
大多数 Linux 实现 chmod 会跟随符号链接,改的是目标文件。要改链接本身,需要 chmod -h(并非所有系统支持)。实务建议:不要对符号链接用 chmod,直接改目标文件,避免混淆。
o=(空)和 o-rwx 不是同一回事chmod o= file # 把其他权限设为「空」(直接覆盖成 ---) chmod o-rwx file # 从现有权限里减去 rwx(如果原本没某位, 减了也没事)
多数时候结果一样,但如果其他组原本就有特殊位(如 sticky),o= 会清掉,o-rwx 不会。生产环境用 = 更彻底,用 - 更保守。
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足够,但排查「权限诡异」时要想到后两层。
chmod 改了权限,但 web 服务还是访问不了新手常误以为「改了 chmod 就万事大吉」,结果 web 服务器(以 www-data 用户运行)还是访问不了文件。根因是:权限只是「身份确认后允不允许」,身份本身(chown/chgrp)没对。比如文件是 alice:alice,你 chmod 640(属组只读),但 www-data 既不是 alice 也不是 alice 组成员,就只能用「其他」那组权限(---),自然访问不了。
排查思路:ls -l 看属主属组 → 确认服务运行用户 → 检查该用户属于哪个组 → 决定它用 u/g/o 哪组权限。权限和身份要一起考虑,见第 04 节。
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
💡 技巧:如果不确定用哪种,问自己「我知道目标权限的完整八进制吗」——知道就用八进制(更精确),不知道(只关心「加个执行位」这种相对变化)就用符号式。这个二分能覆盖大多数场景。
chmod 有两套写法:符号式(u+x,增量)和八进制(755,整体覆盖)——增量用符号、重置用八进制。+(加)、-(减)、=(设为,清掉未提到的)。生产环境优先用 =,更确定。r=4、w=2、x=1 相加,三组拼成三位数。背熟 755/644/700/600 四个常见值。-R 递归的大坑:会把目录的 x 加到文件上,文件应设 644、目录应设 755,用 find -type d/f 分开处理,或用大写 X 只给目录加 x。chmod 改的是目标,不要对链接直接 chmod。0755 和 755 等价(前面 0 是特殊位占位);4755/2755/1755 是带特殊位的权限,慎用。下一节是本章的另一个核心难点:目录权限的真相。目录的 r/w/x 与文件含义完全不同——r 是「能列出文件名」、w 是「能增删文件」、x 是「能进入」。理解了它,你才能破解「为什么能 ls 却打不开文件」「为什么给目录 w 等于送人删除权」这些反直觉现象。