教程

Linux 文件权限:chmod、chown 和 sudo 示例详解

更新于: · Skillaria.Top

Linux 文件权限由三组 rwx 决定,分别针对所有者、所属组和其他人;使用 chmod 修改,既可以用符号形式(chmod u+x),也可以用数字形式(chmod 755,其中 r=4、w=2、x=1)。chown 用于更改所有者,需要管理员权限的操作通过 sudo 执行;出现 Permission denied 通常意味着你的用户对文件或路径上的某个目录缺少所需权限。

Linux 文件权限回答的问题是“谁可以对文件做什么”。每个文件都有所有者、所属组,以及三组权限:针对所有者、针对所属组和针对其他所有人。权限用 chmod 修改,所有者用 chown 修改,需要管理员身份的操作通过 sudo 执行。下面我们讲解如何读懂权限、如何修改权限,以及如何解决 Permission denied 错误。

如何查看文件权限

权限可以在 ls -l 的输出中看到:

$ ls -l
-rw-r--r-- 1 alice developers  1204 Oct 10 14:02 notes.txt
-rwxr-xr-x 1 alice developers   356 Oct 10 14:05 deploy.sh
drwxr-x--- 2 alice developers  4096 Oct 10 13:50 secrets

前十个字符的含义如下:

  • 第一个字符是类型:- 表示普通文件,d 表示目录,l 表示符号链接。
  • 第 2–4 个字符是所有者(user)的权限。
  • 第 5–7 个字符是所属组(group)的权限。
  • 第 8–10 个字符是其他人(others)的权限。

之后依次是硬链接数、所有者(alice)、所属组(developers)、大小、时间和文件名。查看单个文件时,stat 命令很方便:

$ stat -c '%A %a %U:%G %n' deploy.sh
-rwxr-xr-x 755 alice:developers deploy.sh

r、w、x 的含义

同一种权限对文件和目录的含义不同,这是造成混淆的主要原因。

权限对文件对目录
r(read,读)读取内容查看文件列表(ls)
w(write,写)修改内容在目录中创建、删除和重命名文件
x(execute,执行)作为程序运行进入目录(cd),并通过路径访问其中的文件

请注意:对于目录,只要有 w 和 x 权限,就可以删除其中的文件,即使你对文件本身没有写权限。没有目录的 x 权限,即使文件本身允许读取,也无法打开目录中的文件。

系统按以下顺序检查权限:如果你是所有者,就应用所有者的权限;否则,如果你属于文件所属组,就应用组权限;否则,应用其他人的权限。root 用户会跳过读写的权限检查。

数字形式:755、644、600

每种权限都有一个数值:r = 4,w = 2,x = 1。三组权限各自的数值相加,得到一个 0 到 7 之间的数字。

数字权限计算
7rwx4+2+1
6rw-4+2
5r-x4+1
4r--4
0---0

下面几组常用的权限值值得记住:

模式形式用途
644rw-r--r--普通文件、配置文件、HTML
755rwxr-xr-x目录、脚本和程序
600rw-------私有 SSH 密钥、包含密码的文件
700rwx------目录 ~/.ssh、个人目录
640rw-r-----由服务所属组读取的配置文件
777rwxrwxrwx所有人可做所有操作——几乎永远不需要

chmod 命令:如何修改权限

数字模式

数字形式一次性设置全部权限:

chmod 644 index.html
chmod 755 deploy.sh
chmod 600 ~/.ssh/id_ed25519

符号模式

符号形式只修改指定的部分,不影响其他权限。对象:u 所有者,g 所属组,o 其他人,a 所有人。操作:+ 添加,- 移除,= 精确设置。

chmod +x deploy.sh        # 允许运行
chmod u+x,g-w file        # 所有者可执行,组去掉写权限
chmod o-rwx secrets/      # 其他人没有任何权限
chmod g=rx app/           # 组只保留读取和进入目录的权限

递归修改:文件和目录分别处理

-R 选项会把权限应用到整个目录树。但 chmod -R 755 会让所有文件都变成可执行,这通常并不需要。更好的做法是用 find 分别处理文件和目录:

find /srv/site -type d -exec chmod 755 {} +
find /srv/site -type f -exec chmod 644 {} +

还有一个简短的写法:大写的 X 只会给目录,以及已经具有执行权限的文件添加执行权限。

chmod -R u=rwX,go=rX /srv/site

chown 命令:更改所有者和所属组

只有 root 可以更改文件的所有者,因此 chown 通常要通过 sudo 运行。

sudo chown alice report.txt               # 所有者
sudo chown alice:developers report.txt    # 所有者和所属组
sudo chown :www-data index.html           # 仅所属组
sudo chown -R www-data:www-data /var/www/site

如果只想更改所属组,可以使用单独的命令 chgrp:sudo chgrp developers report.txt。你所属的组可以用 id 或 groups 查看。

$ id
uid=1000(alice) gid=1000(alice) groups=1000(alice),27(sudo),1001(developers)

把用户加入某个组:sudo usermod -aG developers bob。选项 -a 必不可少:没有它,用户会被从所有其他附加组中移除。新组在重新登录后才会生效。

sudo:以管理员身份执行操作

sudo 以 root(或其他指定用户)的身份执行一条命令,并要求输入你自己的密码,而不是 root 的密码。所有调用都会写入日志,因此可以看出是谁执行了什么操作。

sudo apt update
sudo systemctl restart nginx
sudo -u postgres psql       # 以 postgres 用户的身份运行
sudo -i                     # 交互式的 root shell
sudo -l                     # 查看我被允许执行哪些命令

谁可以执行什么操作,由 /etc/sudoers 和 /etc/sudoers.d/ 目录中的文件规定。编辑这些文件时只能使用 sudo visudo:它会检查语法,因此文件中的错误不会让你失去 sudo 权限。在 Ubuntu 中,sudo 权限通过加入 sudo 组授予;在 RHEL 系列系统中,则通过 wheel 组授予。

# /etc/sudoers.d/deploy — 用户 deploy 只允许重启 nginx
deploy ALL=(root) NOPASSWD: /usr/bin/systemctl restart nginx

为什么 sudo echo > file 不起作用

这是一个常见的陷阱:

$ sudo echo "127.0.0.1 test.local" >> /etc/hosts
bash: /etc/hosts: Permission denied

重定向 >> 是由你的 shell 执行的,而不是由 sudo 执行的,因此文件是在没有 root 权限的情况下打开的。正确的做法是使用 tee:

echo "127.0.0.1 test.local" | sudo tee -a /etc/hosts

Permission denied:原因和解决方法

Permission denied 表示内核拒绝了你的进程的操作。排查步骤始终相同:我是谁(id),文件的所有者和权限是什么(ls -l),路径上每个目录的权限是什么(namei -l)。

$ namei -l /srv/app/config/app.env
f: /srv/app/config/app.env
drwxr-xr-x root  root  /
drwxr-xr-x root  root  srv
drwxr-x--- deploy deploy app
drwxr-xr-x deploy deploy config
-rw-r----- deploy deploy app.env

可以看到,目录 app 对其他人是关闭的:不属于 deploy 组的用户无法继续深入,无论文件本身的权限如何。

脚本无法运行

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

文件没有执行权限。解决办法是 chmod +x deploy.sh,或者通过解释器运行:bash deploy.sh。如果分区是以 noexec 选项挂载的(/tmp 常见这种情况),就无法直接运行其中的文件,只能使用第二种方法。

无法写入系统目录

/etc、/usr、/var/www 中的文件属于 root 或系统用户。一次性修改可以使用 sudo;长期工作则应该把权限授予某个组,而不是授予所有人。

Web 服务器返回 403

Nginx 或 Apache 以 www-data 用户运行(在 Debian 和 Ubuntu 中)。它需要读取文件的权限,以及路径上所有目录的 x 权限。解决方法:sudo chown -R www-data:www-data /var/www/site,或者将目录设为 755、文件设为 644。

SSH 不接受密钥

如果密钥的权限过于开放,SSH 会拒绝使用。私钥的权限必须是 600,目录 ~/.ssh 必须是 700,服务器上的 authorized_keys 文件必须是 600。

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

无法访问 Docker

出现 permission denied while trying to connect to the Docker daemon socket 说明你不在 docker 组中。执行 sudo usermod -aG docker $USER,然后重新登录。请注意,这个组的成员实际上等同于拥有 root 权限。

为什么 chmod 777 是个坏主意

“直接 chmod 777 就行了”的建议确实能消除错误,但它会让系统中的每个用户和每个进程都能写入该文件。如果 Web 应用被攻破,攻击者就能篡改这些文件。正确的做法是弄清楚哪个用户需要访问,然后通过所有者或所属组只授予他所需的权限。

umask:默认权限

新建文件的权限会受 umask 掩码影响。常见的值 022 会让文件以 644 创建,目录以 755 创建。

$ umask
0022

总结

Linux 的权限就是三组 rwx,分别针对所有者、所属组和其他人。chmod 以数字(755、644、600)或符号形式修改权限,chown 修改所有者,sudo 则允许以 root 身份执行单独的命令。遇到 Permission denied 时,请检查用户、文件权限以及路径上每个目录的权限,不要用 777 来掩盖问题。用户、组、权限和 sudo 都会在 Linux 课程中结合实践详细讲解。

常见问题

chmod 755 是什么意思?

所有者可以读、写和执行(7),所属组和其他人可以读和执行(5)。这是目录和脚本的标准设置。

chmod 和 chown 有什么区别?

chmod 修改权限(允许对文件做什么),chown 修改所有者和所属组(这些权限属于谁)。

怎样给用户 sudo 权限?

在 Ubuntu 和 Debian 中,执行 sudo usermod -aG sudo 用户名 将其加入 sudo 组;在 RHEL 系列系统中,加入 wheel 组。重新登录后生效。

4755 权限和 SUID 位是什么?

最前面的数字 4 表示启用 SUID:程序以文件所有者的身份运行,而不是以启动者的身份运行。例如 passwd 就是这样工作的;在 ls 的输出中,所有者的 x 位置会显示为 s。

为什么 root 可以读取权限为 000 的文件?

内核不会对 root 检查普通的读写权限。若要限制 root,只能借助其他机制,例如 SELinux、AppArmor,或者不可变属性 chattr +i。

通过视频学习本主题

课程“Linux: с нуля до уверенного администрирования”结合实践详细讲解了这一主题。

前往课程