约 7 分钟读完 · 更新于 2026-10-21 · 文中每条都能在下面的配套工具里动手验证
ls -l 的第二段是九个字符,分三组:属主 u、属组 g、其他人 o,每组三位 rwx。r 是读(能打开文件、能列出目录),w 是写(能改内容、能在目录里增删文件),x 是执行(能运行文件、能进入目录)。四个最常见的报错原因:文件本身缺执行位、路径上某一层目录缺 x、文件属于别人而你的用户既不是属主也不在属组、以及在 noexec 或 SELinux 开启的挂载点上执行。按顺序查这四类,比逐个 chmod 试错快得多。
每个数字是三位 rwx 的加权和:读 4、写 2、执行 1。相加得到这一位的值,所以 5 = 4+1(只读可执行)、6 = 4+2(可读写不可执行)、7 = 4+2+1(读写执行全开)、4 = 只读。三位数字从左到右分别对应属主、属组、其他人。5 这个数字在 755 里出现两次、在 644 里出现一次,含义都是「只读可执行」——目录上这是能进入能列目录,文件上这是能运行但不能改。
| 数字 | 符号 | 含义 | 目录上的意思 | 文件上的意思 |
|---|---|---|---|---|
| 0 | --- | 完全没有权限 | 不能用 cd 进入,也不能 ls | 不能读不能改不能跑 |
| 1 | --x | 仅执行 | 可以 cd 进去,但 ls 看不到内容 | 能运行(常配合 4 变成 5) |
| 4 | r-- | 仅读 | 能 ls,不能 cd | 能 cat,不能改 |
| 5 | r-x | 读 + 执行 | 能 cd 进去、只读地 ls | 能运行脚本或程序 |
| 6 | rw- | 读 + 写 | 能在目录里增删文件 | 能改内容,但不能直接运行 |
| 7 | rwx | 全开 | 能进、能增删、能列 | 能改,也能直接运行 |
| 权限 | 符号写法 | 适合什么 | 典型例子 |
|---|---|---|---|
| 644 | rw-r--r-- | 静态资源、只读配置、文档 | README、nginx 里的静态文件、公开配置 |
| 755 | rwxr-xr-x | 脚本、可执行文件、公开目录 | deploy.sh、二进制、/var/www/html |
| 600 | rw------- | 只允许属主访问的私密内容 | SSH 私钥、.env、密码文件 |
| 700 | rwx------ | 属主完全控制的私有目录 | ~/.ssh、~/.config 应用配置目录 |
| 775 | rwxrwxr-x | 同一团队需要共同写入的目录 | 共享构建产物目录、上传目录 |
| 640 | rw-r----- | 属主写、属组只读 | 只有运维组需要读的配置 |
| 777 | rwxrwxrwx | 几乎不该用 | 共享目录的妥协,常伴随安全审计问题 |
文件的 rwx 语义和目录不一样,混起来就会出现「ls -l 明明是 rwxr-xr-x,脚本却还是 Permission denied」这种困惑。目录上:r 决定能不能看到里面的文件名(能列出条目),w 决定能不能在里面新建、删除、改名(哪怕一个条目名字都看不到也能删,靠的是 w 加父目录的 x),x 决定能不能 cd 进去、能不能用绝对路径访问里面的文件——没有 x,路径上的每一层都是墙。所以正确组合是「r-x 用于只读遍历目录」,写成 644 的目录会让人完全进不去。
新建文件的权限不是直接取你写的数字,而是「请求的权限」再被 umask 按位抹掉。普通文件请求 666(读写),目录请求 777,umask 022 会把 w 位从 others 抹掉,于是文件落地是 644、目录落地是 755;umask 077 则把 group 和 others 全部抹掉,文件变成 600、目录变成 700。umask 是在 shell 启动时从配置里读进进程的,所以「同一条命令在 A 机器是 644、在 B 机器是 600」通常是 umask 不同。改法有两条:临时用 umask 022 调整当前 shell,或直接对目标文件 chmod 显式写死。
chmod 755 run.sh # 数字:三位分别是属主/属组/其他人 chmod u+x,go-w run.sh # 符号:只加执行位,其他人不给写 chmod -R u=rwX,go=rX dir/ # X 只在目录或已有 x 的文件上落 x,比 -R 755 安全 chmod --reference=a.txt b.txt # 抄 a.txt 的权限给 b.txt chown user:group b.txt # 改属主属组(-R 递归同样要谨慎)
ls -ld /srv /srv/app /srv/app/data # 路径上每一层都需要 x ls -l run.sh # 文件本身需要 x(通常是 644) id # 我是属主吗?在属组里吗? mount | grep " on / " # 是不是 noexec 挂载 namei -l /srv/app/data # 一行看完整条路径每一段权限
递归会把整棵子树的权限一起改掉,常见的两种翻车:把 .ssh 目录改成 777 后 ssh 会直接拒绝使用私钥(要求 600/700),把数据库的数据目录改成 777 会让服务以错误身份写入或被其他用户篡改。养成三个习惯:递归时用 -R 前的通配符限定目录而不是父目录,chmod -R 777 改成对目录 755、文件 644 两步走;改之前用 ls -lR 或 find 先看清影响范围;权限属于私有文件(.env、密钥、.git 里的对象)时优先用 chown 交给服务账号,而不是把权限开到人人可写。
只差「执行位」和「组用户的写位」。755 = rwxr-xr-x,属主可读写执行、其他人可读可执行;644 = rw-r--r--,所有人都没有执行位。结论先行:755 给脚本和可执行文件,644 给纯文本和静态资源。用 chmod 计算器勾选读写执行就能看到数字与 rwx 的实时互转。
按顺序四步:① ls -l 看文件有没有 x 位(脚本最常见);② ls -ld 逐层看路径上每个目录有没有 x,目录缺 x 就进不去;③ id 确认自己是属主或属组里的人;④ mount | grep 检查是不是 noexec 挂载。一行版本是 namei -l 完整路径,能一次看完每一段的权限。
递归 777 会把私有文件一起开放:.ssh 权限过宽会导致 ssh 拒绝使用密钥,数据库数据目录 777 会让服务写错身份或被篡改。替代做法是目录 755、文件 644 两步走,或用 chmod -R u=rwX,go=rX(X 只在目录上落执行位)。私有内容应该用 chown 交给服务账号,而不是让所有人可写。
umask 会把新建文件请求的权限按位抹掉:文件请求 666、目录请求 777,umask 022 把其他人的写位抹掉,于是文件 644、目录 755;umask 077 则变成 600 和 700。它在 shell 启动时确定,所以同一条命令在不同机器结果不同。要固定结果就显式 chmod,或在脚本里先设置 umask。