3.2. 文件

在所有类 Unix 系统中,信息的主要仓库是文件树,根目录为 ``/''. 文件树是目录的层级集合,每个目录可能包含文件系统对象 (FSO)。

在 Linux 中,文件系统对象 (FSO) 可以是普通文件、目录、符号链接、命名管道(也称为先进先出或 FIFO)、套接字(见下文)、字符特殊(设备)文件或块特殊(设备)文件(在 Linux 中,此列表在 find(1) 命令中给出)。其他类 Unix 系统具有相同或相似的 FSO 类型列表。

文件系统对象被收集在文件系统上,文件系统可以被挂载和卸载到文件树中的目录上。文件系统类型(例如,ext2 和 FAT)是一组特定的约定,用于在磁盘上排列数据以优化速度、可靠性等等;许多人使用术语“文件系统”作为文件系统类型的同义词。

3.2.1. 文件系统对象属性

不同的类 Unix 系统支持不同的文件系统类型。文件系统可能具有略微不同的访问控制属性集,并且访问控制可能受挂载时选择的选项影响。在 Linux 上,ext2 文件系统目前是最流行的文件系统,但 Linux 支持大量的文件系统。大多数类 Unix 系统也倾向于支持多种文件系统。

类 Unix 系统上的大多数文件系统至少存储以下内容

以下属性是 ext2 文件系统上 Linux 独有的扩展,尽管许多其他文件系统具有类似的功能

其他常见的扩展包括某种指示“无法删除此文件”的位。

许多这些值可以在挂载时受到影响,因此,例如,某些位可以被视为具有特定值(无论它们在介质上的值如何)。有关此方面的更多信息,请参阅 mount(1)。这些位很有用,但请注意,其中一些位旨在简化易用性,并且实际上不足以阻止某些操作。例如,在 Linux 上,使用“noexec”挂载将禁用在该文件系统上执行程序;正如手册中指出的,它旨在用于挂载包含不兼容系统二进制文件的文件系统。在 Linux 上,此选项不会完全阻止某人运行文件;他们可以将文件复制到其他地方运行,甚至可以使用命令“/lib/ld-linux.so.2”直接运行该文件。

某些文件系统不支持其中一些访问控制值;同样,有关如何处理这些文件系统的信息,请参阅 mount(1)。特别是,许多类 Unix 系统支持 MS-DOS 磁盘,默认情况下,这些磁盘仅支持很少的这些属性(并且没有定义这些属性的标准方法)。在这种情况下,类 Unix 系统会模拟标准属性(可能通过特殊的磁盘文件来实现它们),并且这些属性通常受 mount(1) 命令的影响。

重要的是要注意,对于添加和删除文件,除非类 Unix 系统支持更复杂的方案(例如 POSIX ACL),否则只有文件目录的权限位和所有者才真正重要。除非系统有其他扩展,并且 stock Linux 2.2 没有,否则如果包含目录允许,即使权限位中没有权限的文件仍然可以被删除。此外,如果祖先目录允许其子目录被某些用户或组更改,那么该目录的任何后代都可以被该用户或组替换。

IEEE POSIX 安全标准草案定义了一种用于真正 ACL 的技术,该技术支持用户和组列表及其权限。不幸的是,这并未得到广泛支持,并且在类 Unix 系统之间的支持方式也不完全相同。例如,Stock Linux 2.2 在文件系统中既没有 ACL,也没有 POSIX 功能值。

值得注意的是,在 Linux 中,Linux ext2 文件系统默认情况下为 root 用户保留少量空间。这是一种针对拒绝服务攻击的部分防御;即使某个用户填满了与 root 用户共享的磁盘,root 用户仍然剩下一点空间(例如,用于关键功能)。默认值为文件系统空间的 5%;请参阅 mke2fs(8),特别是其“-m”选项。

3.2.2. 创建时间初始值

在创建时,适用以下规则。在大多数 Unix 系统上,当通过 creat(2) 或 open(2) 创建新的文件系统对象时,FSO UID 设置为进程的 EUID,FSO 的 GID 设置为进程的 EGID。Linux 的工作方式略有不同,因为它具有 FSUID 扩展;FSO 的 UID 设置为进程的 FSUID,FSO GID 设置为进程的 FSGUID;如果包含目录的 setgid 位已设置或文件系统的“GRPID”标志已设置,则 FSO GID 实际上设置为包含目录的 GID。包括 Sun Solaris 和 Linux 在内的许多系统也支持 setgid 目录扩展。如前所述,此特殊情况支持“项目”目录:要创建“项目”目录,请为项目创建一个特殊组,为该项目创建一个由该组拥有的目录,然后使该目录成为 setgid:放置在那里的文件自动由项目拥有。同样,如果在 setgid 位已设置(且文件系统 GRPID 未设置)的目录中创建新的子目录,则新的子目录也将设置其 setgid 位(以便项目子目录将“做正确的事”。);在所有其他情况下,新文件的 setgid 位都是清除的。这是“用户私有组”方案(由 Red Hat Linux 和其他一些方案使用)的基本原理。在此方案中,每个用户都是一个“私有”组的成员,该组只有他们自己作为成员,因此他们的默认设置可以允许该组读取和写入任何文件(因为他们是该组的唯一成员)。因此,当文件的组成员身份以这种方式转移时,读取和写入权限也会转移。FSO 基本访问控制值(读取、写入、执行)是从(请求的值 & ~ 进程的 umask)计算得出的。新文件始终以清除的粘滞位和清除的 setuid 位开头。

3.2.3. 更改访问控制属性

您可以使用 chmod(2)、fchmod(2) 或 chmod(1) 设置大多数这些值,但另请参阅 chown(1) 和 chgrp(1)。在 Linux 中,某些 Linux 独有的属性使用 chattr(1) 进行操作。

请注意,在 Linux 中,只有 root 用户可以更改给定文件的所有者。某些类 Unix 系统允许普通用户将其文件的所有权转移给其他人,但这会引起并发症,并且 Linux 禁止这样做。例如,如果您尝试限制磁盘使用量,则允许此类操作将允许用户声称大文件实际上属于某些其他“受害者”。

3.2.4. 使用访问控制属性

在 Linux 和大多数类 Unix 系统下,仅在文件打开时才检查读取和写入属性值;不会在每次读取或写入时重新检查它们。尽管如此,大量调用确实会检查这些属性,因为文件系统对于类 Unix 系统至关重要。检查这些属性的调用包括 open(2)、creat(2)、link(2)、unlink(2)、rename(2)、mknod(2)、symlink(2) 和 socket(2)。

3.2.5. 文件系统层次结构

多年来,人们建立了一些关于“将文件放置在何处”的约定。在可能的情况下,请在层次结构中放置信息时遵循惯例用法。例如,将全局配置信息放置在 /etc 中。文件系统层次结构标准 (FHS) 尝试以逻辑方式定义这些约定,并被 Linux 系统广泛使用。FHS 是先前 Linux 文件系统结构标准 (FSSTND) 的更新,它吸收了 Linux、BSD 和 System V 系统的经验教训和方法。有关 FHS 的更多信息,请参阅 http://www.pathname.com/fhs。有关这些约定的摘要,请参阅 Linux 的 hier(5) 和 Solaris 的 hier(7)。有时不同的约定会不一致;在可能的情况下,使这些情况在编译或安装时可配置。

我应该注意到,FHS 已被 Linux 标准库 采用,该库正在开发和推广一套标准,以提高 Linux 发行版之间的兼容性,并使软件应用程序能够在任何兼容的 Linux 系统上运行。