Skip to content

chmod 命令详解:改文件和目录的权限位 ​

本文是 Linux 命令速查 中 chmod 的从 0 到 1 详解。 目标:把 chmod --help 里的每个选项讲清楚,顺便把「数字权限」和「SUID/Sticky 特殊位」一次讲透,多看几遍后你在服务器上敲 chmod --help 就知道该用哪个选项。 环境依据:GNU coreutils 8.32(Ubuntu 22.04 自带;RHEL/Rocky 自带版本用法一致)。

一、命令是干什么的 ​

chmod = change mode(改变模式/权限),用来改一个文件或目录「谁能读、谁能写、谁能执行」。

ls -l 看到的第一串 -rwxr-xr-x 就是权限位,chmod 就是改它的工具。

  • 改单个文件权限:chmod 644 文件名;
  • 递归改一整个目录:chmod -R 755 目录;
  • 用符号加减权限:chmod u+x 文件名。

类比:就像 Windows 右键文件 → 属性 → 安全里勾选「只读/可写」,但 Linux 把权限分成了属主 / 属组 / 其他人三档,每档都能单独设读(r)写(w)执行(x)。

二、命令语法 ​

bash
chmod [选项] 模式[,模式]... 文件...
chmod [选项] 八进制模式 文件...
chmod [选项] --reference=参考文件 文件...
  • 模式:两种写法——数字(如 755)或符号(如 u+x);
  • 文件:要改谁,可一次给多个;
  • --reference=参考文件:照着另一个文件的权限来设,不自己算数字。

三、选项全表(对照 chmod --help) ​

chmod 本身选项很少,真正的复杂度在「模式」怎么写。先看选项:

选项中文含义什么场景用
-R,--recursive递归改目录下所有内容改整个目录树权限时
-c,--changes只在权限真的变了时才报告比 -v 安静
-v,--verbose每个文件都打印处理过程想看它改了什么
-f,--silent,--quiet压制大部分错误信息脚本里不想看报错
--reference=RFILE用参考文件的权限,不写数字让新文件权限跟某个文件一致
--preserve-root对 / 递归时拒绝执行(安全)默认就是这样保护根目录

权限位本身(最重要的知识) ​

ls -l 看到的 9 位权限,分三组,每组三位:

text
rwx  r-x  r-x
─┬┘  ─┬─  ─┬─
属主  属组  其他人
 u    g    o
  • r = read 读(4);w = write 写(2);x = execute 执行(1);- = 没这权限(0)。
  • 数字法:三位一组加起来。rwx=4+2+1=7,r-x=4+1=5,r--=4。所以 755 = 属主 rwx、属组 r-x、其他人 r-x。
  • 符号法:u(属主)/g(属组)/o(其他人)/a(所有人),配 +(加)/-(减)/=(设成),再加 rwx。如 u+x 给属主加执行权。

三种特殊权限位 ​

特殊位数字加在哪效果
SUID4属主的 x 位谁执行这个程序,就临时以文件属主身份运行(如 passwd 命令)
SGID2属组的 x 位对目录:新建文件自动继承目录的属组
Sticky(粘滞位)1其他人的 x 位目录里的文件只有属主/root 能删(如 /tmp)

SUID/Sticky 在 ls -l 里显示成 s 和 t:-rwsr-xr-x 就是带 SUID;drwxrwxrwt 就是带粘滞位。

四、由浅入深的典型示例 ​

示例 1:数字法给文件设标准权限 ​

bash
echo "hello" > a.txt
chmod 644 a.txt
ls -l a.txt
text
-rw-r--r-- 1 user user 6 Sep 30 23:29 a.txt

644 = 属主 rw-(6)、属组 r--(4)、其他人 r--(4)。这是普通文本文件最标准的权限:属主能改,别人只能读。

示例 2:符号法给属主加执行权 ​

bash
chmod u+x a.txt
ls -l a.txt
text
-rwxr--r-- 1 user user 6 Sep 30 23:29 a.txt

u+x = user + execute。第一位从 - 变成 x,这个脚本就能 ./a.txt 跑了。想同时给属组和其他人读:chmod u+x,go+r a.txt。

示例 3:组合符号法减权限 ​

bash
chmod g-w,o-rwx a.txt
ls -l a.txt
text
-rwxr----- 1 user user 6 Sep 30 23:29 a.txt

属组去掉写、其他人去掉所有权限。现在除了属主,谁都读不了这个文件。

示例 4:递归改整个目录 ​

bash
chmod 755 -R sub
ls -ld sub sub/b.txt
text
drwxr-xr-x 2 user user 4096 Sep 30 23:29 sub
-rwxr-xr-x 1 user user    6 Sep 30 23:29 sub/b.txt

-R 把目录和里面所有文件一起改。755 = 属主全权、其他人可读可进不可写。注意:目录要 x 才能进去(cd),所以目录一般是 755 而文件是 644。

示例 5:SUID 位(看 ls 怎么显示) ​

bash
cp /bin/true suid_demo
chmod 4755 suid_demo
ls -l suid_demo
text
-rwsr-xr-x 1 user user 26936 Sep 30 23:29 suid_demo

注意属主那一位从 x 变成了 s——这就是 SUID。4755 开头的 4 就是 SUID。普通用户跑这个程序时,会临时拥有文件属主的权限。系统里 passwd 命令就是 SUID root,所以你改密码时才能写 /etc/shadow。

示例 6:Sticky 粘滞位(/tmp 的保护) ​

bash
chmod 1777 sub
ls -ld sub
text
drwxrwxrwt 2 user user 4096 Sep 30 23:29 sub

其他人那一位变成了 t——粘滞位。1777 开头的 1 就是它。意思是:虽然所有人都能在这个目录里写(777),但只有文件属主自己能删自己的文件。/tmp 就是这个权限,防止互相删对方的临时文件。

示例 7:照着参考文件设权限 ​

bash
chmod --reference=a.txt sub/b.txt
ls -l sub/b.txt

不想自己算数字,就让 sub/b.txt 跟 a.txt 权限一模一样。批量统一权限时很方便。

示例 8:常用「文件 vs 目录」权限速记 ​

bash
# 脚本:可执行
chmod 755 deploy.sh
# 配置文件:属主可写,其他人只读
chmod 644 /etc/nginx/nginx.conf
# 私密文件:只有属主能读写
chmod 600 ~/.ssh/id_rsa

600 = 只有属主能读写,这是私钥文件的标准权限(权限太开放 ssh 会拒绝用)。

五、高频组合速记 ​

命令用途
chmod 644 文件普通文件(属主可写,其他人只读)
chmod 755 文件/目录可执行脚本 / 可进入的目录
chmod 600 文件私密文件(只有自己能读写)
chmod 700 目录只有自己能进的目录
chmod u+x 脚本给脚本加执行权(最常用)
chmod -R 755 目录递归改目录树
chmod +x 脚本给所有人加执行权
chmod 1777 目录粘滞位(公共可写但只能删自己的)

六、RHEL 系与 Debian 系差异 ​

chmod 属 GNU coreutils,两系用法完全一致。仅有的细微点:

  • RHEL 开了 SELinux 的系统上,光改 rwx 权限有时还不够,还要看 SELinux 上下文(ls -Z),那是另一层;
  • 默认新建文件权限由 umask 决定,两系默认 umask 略有不同(Ubuntu 一般 022),但 chmod 行为本身没差。

七、新手易错点 ​

  1. 文件和目录的 x 含义不同:目录的 x 是「能不能进去(cd)」,不是能不能运行。目录没 x 权限,连 ls 都进不去。
  2. 777 是危险习惯:图省事 chmod -R 777 把所有文件都变成所有人可写可执行,等于把门敞开。能用 644/755 就别用 777。
  3. -R 会把文件也加上 x:chmod -R 755 目录 会让里面的文本文件也变成可执行。更稳妥的做法是先 find 目录 -type d -exec chmod 755 {} \; 再 find 目录 -type f -exec chmod 644 {} \;。
  4. SUID 不要乱加:给普通程序设 SUID root 是严重安全隐患——任何人跑它都会临时变 root。系统自带的 passwd/sudo 除外。
  5. 数字顺序别搞反:chmod 755 是「属主=7、属组=5、其他=5」,从左到右对应 u/g/o。
  6. 改了不生效先看是不是目录:改的是文件权限,但你访问的是目录路径,那要看路径上每一级目录的执行权限。
  7. chmod 不能改属主:改属主用 chown,别和 chmod 搞混。

八、相关命令与文档 ​