文件权限是 Linux 系统的基石之一。你可能遇到过这样的场景:明明用 root 执行脚本一切正常,换成普通用户就报 Permission denied;或者刚搭好的 Nginx 死活无法读取证书文件,折腾半天发现是上层目录权限不对。这些问题的根源,都在于对文件权限理解不够深。
这篇文章不会事无巨细地罗列每一个命令选项,而是从实战出发,把权限管理的核心概念、常用操作、特殊权限以及排障思路串起来。无论是刚接触 Linux 的新手,还是想查漏补缺的老手,都能有所收获。

一、先从 ls -l 的输出说起
随便找个目录执行 ls -l,你会看到类似这样的输出:
-rw-r--r-- 1 root root1234 Apr8 10:00 config.conf drwxr-xr-x 2 root root4096 Apr8 09:00 data -rwsr-xr-x 1 root root 56789 Apr7 18:00 suid_prog
先看第一列,一共 10 个字符,我习惯把它拆成四段来理解:
位置 | 含义 | 例子中的值 |
第1个字符 | 文件类型 | - 普通文件,d 目录,l 符号链接,b 块设备,c 字符设备 |
第2-4字符 | 所有者(user)权限 | rw- 表示可读可写不可执行 |
第5-7字符 | 所属组(group)权限 | r-- 表示只读 |
第8-10字符 | 其他人(other)权限 | r-- 表示只读 |
上面例子中 -rw-r--r-- 解读:这是一个普通文件,所有者可读写,组用户只读,其他人只读。
关于 rwx 对文件和目录的含义差异,很多人一开始会混淆:
·文件:r 读内容,w 修改内容,x 执行(脚本或二进制)
·目录:r 列出目录内容(需要配合 x),w 在目录内创建/删除文件(需要配合 x),x 进入目录(cd)
目录如果没有 x 权限,哪怕有 r 也看不到里面的文件名——这算是一个经典坑点。

二、用户和组:权限的主体
权限是“谁对哪个文件能做什么”,所以必须先搞清楚“谁”。
Linux 中的“谁”分为三级:
1.所有者(user):默认是创建文件的用户,可以用 chown 改。
2.所属组(group):默认是创建用户的主组,可以用 chgrp 改。
3.其他人(other):既不是所有者也不在所属组里的用户。
每个用户有一个 UID(0 是 root),每个组有一个 GID。这些信息存放在 /etc/passwd 和 /etc/group 里。日常不需要直接编辑这两个文件,用命令操作更安全。
几个必须掌握的用户/组管理命令:
命令 | 作用 | 常用示例 |
useradd | 创建用户 | useradd -m -s /bin/bash deployer |
usermod | 修改用户属性 | usermod -aG wheel deployer(追加到 wheel 组) |
userdel | 删除用户 | userdel -r deployer(同时删家目录) |
groupadd | 创建组 | groupadd appgroup |
id | 查看用户的 UID/GID/组 | id deployer |
whoami / who | 当前登录用户 | 排障时常用 |
一个实用经验:不要轻易删除用户。如果只是想禁用,用 usermod -L 锁定密码即可,避免后面出现“用户 ID 被复用”导致的文件孤儿问题。

三、核心命令:chmod、chown、chgrp
3.1 chmod:修改权限位
有两种写法:符号模式和数字模式。我建议两种都熟练,因为不同场景下各有便利。
符号模式:u(所有者)、g(组)、o(其他人)、a(全部)+ 添加、- 移除、= 精确设置
chmod u+x script.sh# 所有者加执行权限 chmod g-w config.conf# 组去掉写权限 chmod o=r file.txt# 其他人只读(覆盖原有) chmod a+x *.sh# 所有人加执行
数字模式:用三位八进制数表示 rwx,每位对应一个权限集。r=4, w=2, x=1,求和即可。
chmod 755 script.sh# 所有者 rwx (7),组 r-x (5),其他人 r-x (5) chmod 600 secret.key# 所有者 rw,其他人无任何权限 chmod 644 config.conf# 常见文件默认权限
目录通常需要 755(所有者可读写执行,其他人只读执行)或者 750(组内可访问,外人不可见)。
3.2 chown:修改所有者和组
chown deployer file.txt# 只改所有者 chown :appgroup file.txt# 只改组(注意冒号) chown deployer:appgroup file.txt# 同时改所有者和组 chown -R deployer:appgroup /app# 递归修改,慎用
递归修改时要注意,不要一股脑 -R 覆盖系统目录,否则可能导致服务起不来。
3.3 chgrp:单独修改组
chgrp 其实是 chown 子集,但单独记一下无妨:
chgrp appgroup file.txt

四、默认权限面具:umask
你有没有好奇过:为什么新建的文件权限是 644,新建的目录是 755?答案藏在 umask 里。
umask 是一个“权限掩码”,从满权限(文件是 666,目录是 777)中扣除 umask 值得到实际权限。输入 umask 通常看到 0022,第一位是特殊权限位(后面会讲),后三位分别是所有者、组、其他人的掩码。
计算逻辑:
·文件:666 - umask → 644(因为 666 - 022 = 644)
·目录:777 - umask → 755
如果想让组内成员也能编辑新创建的文件,可以设置 umask 002,这样新建文件权限变成 664,目录 775。
修改 umask 可以写在 ~/.bashrc 或 /etc/profile 中,但生产环境不建议随意改全局 umask,容易破坏预期。

五、特殊权限:SUID、SGID、Sticky Bit
这三个是进阶知识点,也是面试常客,更是排障时容易忽略的盲区。
5.1 SUID(Set User ID)
出现在所有者的执行位上,显示为 s(如 -rwsr-xr-x)。当普通用户执行带有 SUID 的程序时,进程的有效用户 ID 变为程序所有者的 ID。
最典型的例子是 /bin/passwd,普通用户用它修改自己的密码,需要写入 /etc/shadow(只有 root 能写),正是 SUID 让 passwd 以 root 身份运行。
设置 SUID:chmod u+s filename移除:chmod u-s filename
风险:任何可执行文件上的 SUID 都可能成为提权漏洞。定期用 find / -perm -4000 -type f 2>/dev/null 审计 SUID 文件是个好习惯。
5.2 SGID(Set Group ID)
·对文件:执行时进程的有效组 ID 变为文件所属组(类似 SUID 的组版本)。
·对目录:在该目录下新建的文件或子目录,会自动继承该目录的所属组,而不是创建者的主组。这在团队协作目录中非常有用。
设置 SGID:chmod g+s directory移除:chmod g-s directory
5.3 Sticky Bit(粘滞位)
作用于目录,显示为其他用户的执行位上 t(如 /tmp 的 drwxrwxrwt)。作用:只有文件所有者、目录所有者或 root 才能删除或重命名该目录下的文件。
典型场景:/tmp 和 /var/tmp。没有 Sticky Bit,任何用户都能删除别人的临时文件,后果不堪设想。
设置 Sticky:chmod +t directory移除:chmod -t directory

六、突破传统权限限制:ACL
传统的 user/group/other 三元组有时不够用。比如:希望某个文件对 userA 只读,对 userB 可写,对 groupX 无权限,但 userA 同时又在 groupX 里。这时候 ACL(访问控制列表)就能派上用场。
检查文件系统是否支持 ACL(大多数现代 Linux 默认支持):
tune2fs -l /dev/sda1 | grep "Default mount options"
常用命令:
·getfacl file:查看 ACL
·setfacl -m u:username:rwx file:给特定用户添加权限
·setfacl -m g:groupname:rx file:给特定组添加权限
·setfacl -x u:username file:移除特定用户的 ACL
·setfacl -b file:清除所有 ACL
示例:让 deployer 用户对 /var/log/app 有写权限,但其他用户只能读。
setfacl -m u:deployer:rwx /var/log/app setfacl -m g:appgroup:rx /var/log/app setfacl -m o:r-x /var/log/app
ACL 的规则优先级是:所有者 > 特定用户 > 特定组 > 其他。用 getfacl 可以清楚看到最终有效权限。

七、隐藏属性:chattr 与 lsattr
有时候你遇到“明明是 root,却无法删除文件”,或者“文件被改后又自动恢复”,那可能是设置了隐藏属性。这些属性是文件系统层面的,独立于 rwx 权限。
属性 | 作用 | 典型场景 |
i (immutable) | 不可修改、删除、重命名,连 root 也不行 | 关键配置文件防误改 |
a (append only) | 只能追加写入,不能删除已有内容 | 日志文件防篡改 |
A | 不更新 atime(访问时间) | 减少磁盘 I/O |
s | 删除时安全覆写(非所有文件系统支持) | 敏感数据 |
chattr +i /etc/hosts# 锁定 hosts 文件 chattr -i /etc/hosts# 解锁 lsattr /etc/hosts# 查看属性
如果你遇到 Operation not permitted 但明明用 root,且权限是 rw-r--r--,大概率是 i 属性在作祟。

八、实战排障:常见 Permission Denied 问题
8.1 脚本无法执行
现象:./script.sh 报 Permission denied。检查:
ls -l script.sh# 看有没有 x 权限 file script.sh# 确认是文本脚本还是二进制 bash script.sh# 如果不加执行权限,可以用解释器直接运行
解决方案:chmod +x script.sh
8.2 目录无法进入
现象:cd dir 报 Permission denied。原因:目录缺少 x 权限。修复:chmod u+x dir(根据需求可能也要给组或其他人)
8.3 能进入目录但无法列出文件
现象:cd dir 成功,但 ls 报 Permission denied。原因:有 x 但没有 r。修复:chmod u+r dir
8.4 能读写文件但无法删除
现象:文件权限是 rw-rw-rw-,删除时报 Permission denied。检查:所在目录的写权限。删除文件本质上是在修改目录的内容,所以需要对父目录有写权限。修复:检查父目录权限,chmod u+w parent_dir/
8.5 Web 服务器无法读取静态资源
现象:Nginx/Apache 返回 403。排查步骤:
1.确认 web 进程用户(通常是 www-data 或 nginx)。
2.检查文件权限:ls -l /path/to/file。
3.检查从根目录到文件路径的每一层目录是否有 x 权限(至少对 web 用户有 r-x)。
4.如果有 SELinux,查看审计日志:ausearch -m avc。
一个真实案例:某天同事把网站目录放在 /home/user/www,结果 Nginx 始终 403。原因就是 /home/user 默认权限是 750,其他用户没有 x 权限,导致 Nginx 无法穿越 /home/user 目录。解决方法:chmod o+x /home/user 或移动目录到 /var/www。
8.6 权限正确但仍无法访问(SELinux)
关闭 SELinux 不是最佳实践,学会排查更专业。临时测试可以 setenforce 0,如果问题消失,说明是 SELinux 策略阻止。修复方法:
ls -Z /path/to/file# 查看文件的安全上下文 restorecon -v /path/to/file# 恢复默认上下文 semanage fcontext -a -t httpd_sys_content_t "/path(/.*)?"# 永久修改策略

九、安全与维护的最佳实践
1.最小权限原则:给用户和进程的权限只需要刚好够用。不要为了省事设置 777。
2.定期审计 SUID 文件:find / -perm -4000 -type f 2>/dev/null,检查是否有不该有的可执行文件带 SUID。
3.敏感文件权限控制:私钥(600)、配置文件(640 或 644)、日志目录(750)。
4.使用 ACL 而非批量改属组:当需要多人不同权限时,ACL 比频繁修改用户属组更干净。
5.chattr 锁定关键文件:/etc/passwd、/etc/shadow、/etc/sudoers 等加上 i 属性,防止被篡改。
6.备份权限状态:重要目录的权限可以导出备份:getfacl -R /app > app_perms.txt,恢复时 setfacl --restore=app_perms.txt。

十、快速参考卡片
你要做什么 | 命令示例 |
查看文件权限 | ls -l file |
给所有者加执行 | chmod u+x file |
设置文件为 644 | chmod 644 file |
递归修改目录权限 | chmod -R 755 dir |
修改所有者 | chown user file |
修改所有者和组 | chown user:group file |
修改组 | chgrp group file |
查看 umask 当前值 | umask |
设置 umask | umask 002 |
设置 SUID | chmod u+s file |
设置 SGID(目录) | chmod g+s dir |
设置 Sticky Bit | chmod +t dir |
查看 ACL | getfacl file |
设置 ACL 给特定用户 | setfacl -m u:alice:rw file |
查看隐藏属性 | lsattr file |
设置不可变 | chattr +i file |

Linux 文件权限体系看似琐碎,但核心思想并不复杂:谁对什么有哪些操作。把这个模型刻在脑子里,遇到权限问题时,你就能有条理地逐层排查,而不是盲目地 chmod 777。