Linux 文件权限到底怎么回事

不讲复杂的 SELinux,只讲日常最常用的文件权限。


从一次报错开始

$ ssh user@server
$ ./deploy.sh
-bash: ./deploy.sh: Permission denied

第一反应是加权限:

chmod 777 deploy.sh

虽然能跑,但 777 意味着任何人都可以改这个文件——这是安全风险。看懂权限之后,你会知道应该用 chmod +x755


先看懂 ls -l 的输出

ls -l deploy.sh
-rwxr-xr-x  1  root  root  123  Apr 28 10:00  deploy.sh

拆成三块来看。

第一块:文件类型和权限(10 个字符)

-  rwx  r-x  r-x
│  └┬─  └┬─  └┬─
│   │    │   └── 其他人(other)
│   │    └────── 同组用户(group)
│   └─────────── 文件所有者(user)
└─────────────── 文件类型(- 普通文件,d 目录,l 符号链接)

每个三位的含义:

r    w    x
读   写   执行
4    2    1
  • rwx = 4+2+1 = 7(可读可写可执行)
  • r-x = 4+0+1 = 5(可读可执行,不可写)
  • r-- = 4+0+0 = 4(只读)
  • --- = 0+0+0 = 0(没有权限)

第二块:所有者和组

root  root
└┬──  └┬──
 │     └── 所属组
 └──────── 文件所有者
  • 谁是这个文件的主人(owner)
  • 这个文件属于哪个(group)

第三块:大小和修改时间

123  Apr 28 10:00
大小   修改时间

三种改权限的命令

chmod — 改权限位

用数字方式(推荐):

chmod 755 deploy.sh    # rwxr-xr-x  所有者可读写执行,其他人只读执行
chmod 644 config.cfg   # rw-r--r--  所有者可读写,其他人只读
chmod 600 id_rsa       # rw-------  只有所有者能读写
chmod 700 private/     # rwx------  只有所有者能进入目录
chmod 777 file         # 不推荐,任何人可读写执行

用字母方式(单次操作可读性更好):

chmod +x deploy.sh     # 加执行权限(不影响已有权限)
chmod -x deploy.sh     # 去掉执行权限
chmod u+w config.cfg   # 给所有者(u)加写(w)权限
chmod g+r config.cfg   # 给组(g)加读(r)权限
chmod o-r config.cfg   # 去掉其他人(o)的读权限
chmod a+x script.sh    # 所有人(a)加执行权限

递归修改(目录及其内部所有文件):

chmod -R 755 /path/to/dir

chown — 改所有者

chown user file.txt                # 改文件所有者为 user
chown user:group file.txt          # 改所有者和组
chown :group file.txt              # 只改组
chown -R user:group /data          # 递归改目录下所有

chgrp — 只改所属组

chgrp developers config.cfg

目录权限和文件权限不一样

这是一定要分清的地方:

权限 对文件的意义 对目录的意义
r(读) 可以查看文件内容 可以列出目录内容(ls)
w(写) 可以修改文件内容 可以创建/删除目录里的文件
x(执行) 可以执行文件(脚本/程序) 可以进入目录(cd)

文件 x 是执行,目录 x 是"穿过"(进入)。

典型配置

chmod 755 /var/www/html       # drwxr-xr-x  可以进入和查看
chmod 700 ~/.ssh              # drwx------  只有自己能进入

目录一般至少需要 r-x(可以 lscd)才有意义。


实战:问题排查

1. 上传的脚本不能执行

$ ./deploy.sh
-bash: ./deploy.sh: Permission denied

解决:

ls -l deploy.sh          # 确认没有 x 权限
chmod +x deploy.sh       # 加执行权限

2. Nginx 报 403 Forbidden

没权限读静态文件:

# 看 Nginx 以什么用户运行
ps aux | grep nginx      # 通常是 www-data 或 nginx

# 看文件权限和所有者
ls -l /var/www/html/

# 修复
sudo chown -R www-data:www-data /var/www/html/
sudo chmod -R 755 /var/www/html/

3. SSH 密钥不生效

$ ssh user@server
Permissions 0644 for 'id_rsa' are too open.

SSH 对私钥文件权限很敏感——太松就拒绝使用:

chmod 600 ~/.ssh/id_ed25519
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys

4. 别人创建的文件我删不掉

$ rm /shared/tmp/file.txt
rm: cannot remove: Permission denied

在目录有写权限才能删里面的文件:

ls -ld /shared/tmp/        # 看目录权限
sudo chmod 777 /shared/tmp/   # 让所有人能删(不推荐)

# 或者加 sticky bit(更合理)
sudo chmod 1777 /shared/tmp/   # 只有文件所有者和 root 能删

SUID / SGID / Sticky Bit

这三个特殊权限不那么常用,但看到了要知道是什么意思。

SUID(Set User ID)

ls -l /usr/bin/passwd
-rwsr-xr-x  1 root  root   ...  /usr/bin/passwd

所有者位的 x 变成了 s。普通用户执行 passwd 时会临时有 root 权限(因为文件所有者是 root),这样才能改 /etc/shadow

数字是 4:chmod 4755 file

SGID(Set Group ID)

ls -l /shared/dir
drwxr-sr-x  2 user  developers   ...

组位的 x 变成了 s。在这个目录里新建的文件,所属组自动继承目录的组。

数字是 2:chmod 2755 dir

Sticky Bit

ls -ld /tmp
drwxrwxrwt  10 root  root   ...

其他人位的 x 变成了 t。在 /tmp 里,任何人都能创建文件,但只能删自己的文件

数字是 1:chmod 1777 /tmp


最常用的权限组合

权限 数字 应用场景
rwx------ 700 私钥目录 ~/.ssh
rw------- 600 私钥文件、密码配置文件
rwxr-xr-x 755 可执行脚本、目录通用权限
rw-r--r-- 644 配置文件、代码文件
rwxr-xr-x + setgid 2755 团队共享目录
rwxrwxrwt 1777 /tmp 类共享临时目录

日常 90% 的情况只用到 755 和 644

chmod 755 script.sh   # 脚本可以执行
chmod 644 config.yaml # 配置文件只读
chmod 600 .secret     # 敏感文件只有自己能看到

一行命令快速定位权限问题

# 找当前目录下权限有问题(太松的)的文件
find . -perm /o+w -ls

# 找没有执行权限的 .sh 文件
find . -name "*.sh" ! -executable -ls

# 看所有者和组
find . ! -user myuser -o ! -group mygroup -ls

总结

你想干什么 用什么命令
让文件能执行 chmod +x file
让文件只有自己能读 chmod 600 file
把文件给另一个用户 chown user file
让目录可进入可查看 chmod 755 dir
删不掉提示 Permission denied 看目录权限,不是看文件权限

关于 777——尽量别用。权限的本质是最小够用原则:需要读就给读,需要执行就给执行,不需要就不给。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐