您将脚本复制到服务器,运行它,却收到“权限被拒绝”的提示。打开日志文件,遇到的也是同样的消息。这两者归根结底是同一件事:Linux 中的每个文件都带有一组权限位,系统在允许您接触文件之前会先检查这些权限位。

在 Linux 中,文件权限、属性和所有权控制系统进程和用户对文件的访问级别。这确保了只有授权的用户和进程才能访问特定的文件和目录。

本指南解释了如何阅读 ls -l 输出中的权限位,读、写、执行在文件和目录上分别意味着什么,以及如何使用 chmod 命令通过符号模式和数字模式来更改权限。

Linux 文件权限

基本的 Linux 权限模型通过将每个系统文件与一个所有者和一个组关联,并为三类不同的用户分配权限访问权来运作:

  • 文件所有者。
  • 组成员。
  • 其他用户(其他人)。

文件所有权可以使用 chown 和 chgrp 命令进行更改。

每类用户都适用三种权限类型:

  • 读权限。
  • 写权限。
  • 执行权限。

这个理念允许您控制哪些用户可以读取文件、写入文件或执行文件。

要查看文件权限,请使用 ls 命令:

终端
ls -l file_name
输出
-rw-r--r-- 1 ggdoc users 12288 Apr 28 10:10 file_name
|[-][-][-]
| |  |  |
| |  |  +----------------------------> 4. 其他用户权限
| |  +-------------------------------> 3. 组权限
| +----------------------------------> 2. 所有者权限
+------------------------------------> 1. 文件类型

第一个字符表示文件类型。它可以是普通文件(-)、目录(d)、符号链接(l)或另一种特殊文件类型。接下来的九个字符表示文件权限,排列为三组。第一组显示所有者权限,第二组显示组权限,最后一组显示其他所有人的权限。

一个可选字符可能紧跟在权限位之后出现。+ 通常表示访问控制列表,而 . 表示安全上下文且没有其他备用访问方法。当两者都不适用时,ls 将此位置留空。其余字段显示硬链接计数、所有者、组、大小、修改时间和文件名。

在上面的例子中,rw-r--r-- 表示文件所有者具有读写权限(rw-),组和其他用户只有读权限(r--)。

这三组权限中的每一组都可以由以下字符构成,同样的字符在文件上或在目录上设置时表示不同的含义:

权限对文件的影响

权限字符对文件的意义
读-文件不可读。您无法查看文件内容。
r文件可读。
写-文件无法更改或修改。
w文件可以被更改或修改。
执行-文件无法被执行。
x文件可以被执行。
s如果出现在 user 组中,则设置 setuid 位。如果出现在 group 组中,则设置 setgid 位。这也意味着 x 标志已设置。
当一个可执行文件上设置了 setuid 或 setgid 标志时,该文件将以文件的所有者和/或组权限来执行。
S与 s 相同,但 x 标志未设置。此标志在文件上很少使用。
t如果出现在 others 组中,则设置 sticky 位。
这也意味着 x 标志已设置。此标志在文件上是无用的。
T与 t 相同,但 x 标志未设置。此标志在文件上是无用的。

权限对目录(文件夹)的影响

目录是特殊类型的文件,可以包含其他文件和目录。

权限字符对目录的意义
读-目录内容无法显示。
r目录条目可以使用 ls 列出。如果没有执行权限,您可以看到它们的名称,但无法访问它们或读取它们的元数据。
写-目录内容无法更改。
w与执行权限一起使用时,允许您创建新文件、删除文件以及重命名目录中的条目。单独的写权限是不够的。
执行-无法遍历该目录,也无法按名称访问其中的条目。
x可以遍历该目录。您可以使用 cd 进入其中,并按名称访问其中的条目,具体访问取决于这些条目自身的权限。
s在 user 组中,表示 setuid 和 x 已设置,尽管 Linux 会忽略目录上的 setuid。在 group 组中,表示 setgid 和 x 已设置。新条目继承目录的组 ID(GID),新的子目录继承 setgid 位。
Ssetuid 或 setgid 位已设置,但相应的 x 位未设置。在 Linux 上,即使以 S 显示,setgid 仍可控制目录上的组继承。
t粘滞位和 others 执行位已设置。在其他可以修改该目录的用户中,只有文件的所有者、目录的所有者或 root 才能删除或重命名其中的文件。
T粘滞位已设置,但 others 执行位未设置。删除限制仍然适用于可以通过所有者或组权限访问该目录的用户。

更改文件权限

文件权限可以使用 chmod 命令更改。只有 root、文件所有者或具有 sudo 权限的用户才能更改文件的权限。使用 chmod 时要格外小心,尤其是在递归更改权限时。该命令可以接受一个或多个文件和/或目录作为参数,用空格分隔。

权限可以使用符号模式、数字模式或参考文件来指定。

符号(文本)方法

使用符号模式时,chmod 命令的语法格式如下:

chmod [OPTIONS] [ugoa…][-+=]perms…[,…] FILE...

第一组标志([ugoa…]),称为用户标志,定义将要修改权限的用户类别。

  • u - 文件所有者。
  • g - 属于该组的用户。
  • o - 所有其他用户。
  • a - 所有用户,等同于 ugo。

当省略用户类别时,chmod 将其视为 a,但受当前 umask 屏蔽的权限不受影响。

第二组标志([-+=]),即操作标志,定义权限是被移除、添加还是设置:

  • - - 移除指定的权限。
  • + - 添加指定的权限。
  • = - 将当前权限更改为指定的权限。如果在 = 符号后未给出权限,则会移除指定用户类别的所有权限。

权限(perms...)使用以下一个或多个字母显式设置:r、w、x、X、s 和 t。当从另一个用户类别复制权限时,请使用 u、g 和 o 中的一个字母。

当为多个用户类别([,…])设置权限时,请使用逗号(不带空格)分隔符号模式。

以下是一些如何在符号模式下使用 chmod 命令的示例:

  • 授予组成员执行该文件的权限,但不能读取和写入它:

    终端
    chmod g=x filename
  • 移除所有用户的写权限:

    终端
    chmod a-w filename
  • 递归地移除其他用户的执行权限:

    终端
    chmod -R o-x dirname
  • 移除除文件所有者外所有用户的读、写和执行权限:

    chmod og-rwx filename

    同样可以通过以下形式实现:

    chmod og= filename
  • 为文件所有者授予读、写和执行权限,为文件所属组授予读权限,其他所有用户无任何权限:

    chmod u=rwx,g=r,o= filename

数字方法

使用数字模式时,chmod 命令的语法格式如下:

chmod [OPTIONS] NUMBER FILE...

使用数字模式时,您可以同时为三个用户类别(所有者、组和其他所有用户)设置权限。

权限数字可以是3位数或4位数。当使用3位数时,第一位代表文件所有者的权限,第二位代表文件所属组的权限,最后一位代表其他所有用户的权限。

每个读、写和执行权限具有以下数值:

  • r(读)= 4
  • w(写)= 2
  • x(执行)= 1
  • 无权限 = 0

特定用户类别的权限数字由该类别的权限值之和表示。

要以数字模式查找文件的权限,请计算每个用户类别的总和。例如,要为文件所有者授予读、写和执行权限,为文件所属组授予读和执行权限,为其他所有用户仅授予读权限,请使用以下值:

  • 所有者:rwx=4+2+1=7
  • 组:r-x=4+0+1=5
  • 其他:r–=4+0+0=4

使用上述方法,我们得到数字 754,表示所需的权限。

要设置 setuid、setgid 和 sticky bit 标志,请使用4位数。

当使用4位数时,请根据以下值计算第一位数字:

  • setuid = 4
  • setgid = 2
  • sticky bit = 1
  • 无特殊位 = 0

接下来的三位数字与使用3位数时的含义相同。

如果第一位数字为0,则可以省略,模式可以用3位数表示。数字模式 0755 等同于 755。

要更深入了解这三个标志在文件和目录上的作用以及各自的安全使用位置,请参阅我们关于 setuid、setgid 和 sticky bit 的指南。

您可以使用 stat 命令以数字记法检查文件的权限:

stat -c "%a" file_name

以下是一些如何在数字模式下使用 chmod 命令的示例:

  • 为文件所有者授予读和写权限,为组成员和其他所有用户仅授予读权限:

    chmod 644 file
  • 为文件所有者授予读、写和执行权限,为组成员授予读和执行权限,其他所有用户无任何权限:

    chmod 750 file
  • 为共享目录中的每个人授予读、写和执行权限,并加上 sticky bit。请保留此权限用于临时目录中,每个人确实需要创建文件的地方,并查看 chmod 777 的含义,了解为什么在其他位置设置全局可写部分存在风险:

    chmod 1777 dirname
  • 为文件的所有者授予文件的读和写权限,以及目录的完全访问权限,同时移除整个目录树中所有组和其他权限:

    chmod -R u=rwX,go= dirname

    大写 X 为目录和已具有执行位的文件添加执行权限。它不会使所有常规文件变为可执行。

新文件的默认权限

您不必在每次创建文件时手动设置权限。通常,程序会为新常规文件请求 666 模式,为新目录请求 777 模式。系统随后清除由 umask 覆盖的位。程序可以请求更严格的模式,并且父目录上的默认 ACL 可以决定权限。

检查当前掩码:

umask
0022

使用 022 掩码时,组和其他用户的写位被清除,因此新文件默认成为 644,新目录成为 755。更严格的掩码 077 会清除两个类别的所有位,得到 600 和 700。我们的 umask 指南涵盖如何计算掩码以及如何使其永久生效。

快速参考

如需可打印的快速参考,请参阅 chmod 速查表。

常见权限值:

模式符号谁可以做什么
777rwxrwxrwx每个人都可以读、写和执行
755rwxr-xr-x所有者完全访问;组和其他读取和执行
750rwxr-x---所有者完全访问;组读取和执行;其他无
700rwx------所有者完全访问;组和其他无
664rw-rw-r--所有者和组读/写;其他仅读
644rw-r--r--所有者读/写;组和其他仅读
600rw-------所有者读/写;组和其他无
400r--------所有者仅读;组和其他无

符号 chmod 示例:

命令效果
chmod u+x file为所有者添加执行权限
chmod g-w file为组移除写权限
chmod o= file移除其他所有用户的所有权限
chmod a+r file为所有人添加读权限
chmod u=rwx,g=rx,o= file为所有类别设置精确权限
chmod -R u=rwX,go=rX dir为每个人授予目录访问权限,但不使每个文件可执行

常见问题解答

chmod 和 chown 有什么区别?
chmod 更改文件上的权限位(读、写、执行)。chown 更改文件的所有者和组。两者都影响谁可以访问文件,但控制不同方面。

chmod 777 表示什么意思,安全吗?
777 为所有者、组和其他所有用户授予读、写和执行权限。它很少适用,应避免在包含敏感数据或由服务执行的 文件 上使用,因为它允许系统上的任何人修改或运行它们。

为什么目录需要执行权限?
在目录上,执行权限允许您进入目录并按名称访问其中的项目。没有执行权限,只能在有限情况下列出目录内容,但无法使用 cd 等命令遍历目录或在其内部打开文件。

什么是 sticky bit,何时使用它?
在可写、可搜索的目录上,sticky bit(模式 1xxx,在 ls -l 中显示为 t)仅允许文件所有者、目录所有者或 root 删除或重命名其中的文件。它用于共享目录(如 /tmp)以防止用户删除彼此的文件。

什么是 setuid,为什么它危险?
当在可执行程序上设置时,setuid 使其以所有者的权限而不是调用者的权限运行。例如,/usr/bin/passwd 是 setuid root,因此普通用户可以更改自己的密码。设计不佳的 setuid 程序可能造成权限提升风险。Linux 忽略解释脚本上的 setuid 和 setgid 位。

如何以数字模式查看权限?
使用 stat 命令:stat -c "%a %n" file。它打印八进制权限值及文件名。