当从另一个操作系统(如 Microsoft Windows)迁移到另一个操作系统时;对最终用户产生重大影响的一件事将是文件系统之间的差异。
什么是文件系统?
文件系统是操作系统用于跟踪磁盘或分区上文件的方法和数据结构;也就是说,文件在磁盘上的组织方式。这个词也用来指代用于存储文件的分区或磁盘,或文件系统的类型。因此,可以说我有两个文件系统,意思是说有两个分区用于存储文件,或者说正在使用扩展文件系统,意思是文件系统的类型。
磁盘或分区与它包含的文件系统之间的区别非常重要。少数程序(包括,理所当然地,创建文件系统的程序)直接在磁盘或分区的原始扇区上操作;如果那里存在文件系统,它将被破坏或严重损坏。大多数程序在文件系统上操作,因此无法在不包含文件系统的分区(或包含错误类型的文件系统的分区)上工作。
在分区或磁盘可以用作文件系统之前,需要对其进行初始化,并将簿记数据结构写入磁盘。这个过程称为创建文件系统。
大多数 UNIX 文件系统类型都有类似的通用结构,尽管确切的细节差异很大。中心概念是 超级块、inode、数据块、目录块 和 间接块。超级块包含有关整个文件系统的信息,例如其大小(此处的确切信息取决于文件系统)。inode 包含有关文件的所有信息,除了其名称。名称存储在目录中,以及 inode 的编号。目录条目由文件名和代表文件的 inode 编号组成。inode 包含多个数据块的编号,这些数据块用于存储文件中的数据。inode 中只有几个数据块编号的空间,但是,如果需要更多,则会动态分配更多指向数据块的指针的空间。这些动态分配的块是间接块;名称表明为了找到数据块,必须首先在间接块中找到其编号。
与 UNIX 类似,Linux 选择使用单一的层次目录结构。一切都从根目录 / 开始,然后扩展到子目录,而不是所谓的“驱动器”。在 Windows 环境中,可以将文件放在几乎任何位置:C 盘、D 盘、E 盘等。这种文件系统被称为层次结构,由程序本身(程序目录)而不是操作系统管理。另一方面,Linux 根据目录对启动过程的重要性,将目录从根目录 / 开始降序排列。
如果您想知道为什么 Linux 使用正斜杠 / 而不是像 Windows 中那样的反斜杠 \,那是因为它只是遵循 UNIX 的传统。Linux 和 Unix 一样,也选择区分大小写。这意味着字符的大小写(无论是否大写)变得非常重要。因此,这与 THIS 不同。这个特性解释了新用户遇到的相当大一部分问题,尤其是在文件传输操作期间,无论是通过可移动磁盘介质(如软盘)还是通过网络(如 FTP)。
文件系统顺序特定于文件的功能,而不是其程序上下文(大多数 Linux 文件系统是“第二扩展文件系统”,简称“EXT2”(也称为“ext2fs”或“extfs2”)或本身是该文件系统的子集,例如 ext3 和 Reiserfs)。正是在这个文件系统中,操作系统决定程序将文件存储到哪些目录中。
如果在 Windows 中安装程序,它通常会将其大部分文件存储在其自己的目录结构中。例如,帮助文件可能位于 C:\Program Files\[程序名称]\ 或 C:\Program Files\[程序名称]\help 或 C:\Program Files\[程序名称]\humpty\dumpty\doo。在 Linux 中,程序将其文档放在 /usr/share/doc/[程序名称] 中,man(ual) 页面放在 /usr/share/man/man[1-9] 中,info 页面放在 /usr/share/info 中。它们被合并到系统层次结构中。
正如所有 Linux 用户都知道的,除非您挂载分区或设备,否则系统不会知道该分区或设备的存在。这可能看起来不是提供对分区或设备访问权限的最简单方法,但是,与其他操作系统相比,它提供了更大的灵活性优势。这种布局,称为统一文件系统,与 Windows 使用的方法相比,确实具有一些优势。让我们以 /usr 目录为例。根目录的这个子目录包含大多数系统可执行文件。使用 Linux 文件系统,您可以选择将其挂载到另一个分区,甚至通过网络从另一台机器挂载,使用无数的协议,如 NFS (Sun)、Coda (CMU) 或 AFS (IBM)。底层系统不会也不需要知道差异。/usr 目录的存在是完全透明的。它看起来像一个本地目录,是本地目录结构的一部分。
合规性要求
+---------+-----------------+-------------+ | | shareable | unshareable | +---------+-----------------+-------------+ |static | /usr | /etc | | | /opt | /boot | +---------+-----------------+-------------+ |variable | /var/mail | /var/run | | | /var/spool/news | /var/lock | +---------+-----------------+-------------+ "Shareable" files are defined as those that can be stored on one host and used on others. "Unshareable" files are those that are not shareable. For example, the files in user home directories are shareable whereas device lock files are not. "Static" files include binaries, libraries, documentation files and other files that do not change without system administrator intervention. "Variable" files are defined as files that are not static. |
这种统一文件系统的另一个原因是,Linux 在运行时使用系统内存缓存大量磁盘访问,以加速这些过程。因此,至关重要的是,这些缓冲区在系统关闭之前被刷新(将其内容写入磁盘)。否则,文件将处于不确定的状态,这当然是非常糟糕的事情。刷新是通过在正确的系统关机期间“卸载”分区来实现的。换句话说,不要在系统运行时关闭系统! 您可能经常侥幸逃脱,因为 Linux 文件系统非常健壮,但也可能对重要文件造成严重破坏。只需按 ctrl-alt-del 或使用正确的命令(例如 shutdown、poweroff、init 0)。这将以一种体面的方式关闭系统,从而保证文件的完整性。
我们 Linux 社区中的许多人已经理所当然地认为存在关于 Linux 的优秀书籍和文档,例如 Linux 文档项目制作的那些。我们已经习惯于来自不同来源(如 Linux FTP 站点和发行版 CD-ROM)的各种软件包平滑地集成在一起。我们已经开始接受我们都知道在任何运行 Linux 的机器上都可以找到诸如 mount 之类的关键文件。我们还理所当然地认为基于 CD-ROM 的发行版可以直接从 CD 运行,并且只消耗少量物理硬盘或 RAM 磁盘来存储一些可变文件,如 /etc/passwd 等。情况并非总是如此。
在 90 年代初中期的 Linux 发展初期,每个发行商都有自己喜欢的在目录层次结构中定位文件的方案。不幸的是,这造成了很多问题。Linux 文件系统结构是一份文档,其创建目的是帮助结束这种混乱局面。通常,创建此文档的组织或文档本身被称为 FSSTND。这是“文件系统标准”的缩写。这份文档已帮助标准化了 Linux 系统上文件系统的布局。自该标准的最初版本发布以来,大多数发行商已经全部或部分采用了它,这极大地造福了所有 Linux 用户。
自该标准的第一个草案以来,FSSTND 项目一直由 Daniel Quinlan 协调,并且该标准的制定是通过一群开发人员和 Linux 爱好者的共识完成的。FSSTND 小组着手实现许多特定目标。首要目标是解决当时现有发行版中存在的一些问题。那时,不可能拥有可共享的 /usr 分区,/bin 和 /usr/bin 之间没有明确的区别,不可能设置无盘工作站,并且对于哪些文件放在哪里存在普遍的困惑。第二个目标是确保与 Linux 和其他类 UNIX 操作系统中已使用的实际标准保持合理的兼容性。最后,该标准必须获得 Linux 社区内开发人员、发行商和用户的广泛认可。如果没有这种支持,该标准将毫无意义,而只是另一种文件系统布局方式。
幸运的是,FSSTND 已经成功,尽管 FSSTND 项目也有一些未设定的目标。FSSTND 不会尝试模仿任何特定的商业 UNIX 操作系统(例如 SunOS、AIX 等)的方案。此外,对于 FSSTND 涵盖的许多文件,该标准并未规定文件是否应该存在,而仅仅是如果文件存在,则应该放在哪里。最后,对于大多数文件,FSSTND 不会尝试规定文件内容格式。(在几个不同的软件包可能需要知道文件格式才能协同工作的情况下,有一些特定的例外。例如,包含持有锁的进程的进程 ID 的锁文件。)总体目标是确定在特定机器上可以找到通用文件的位置(如果它们存在)。FSSTND 项目始于 1993 年 8 月初。从那时起,该文档已经进行了多次公开修订。最新的 v2.3 版本于 2004 年 1 月 29 日发布。
如果您问“这一切的目的是什么?”,那么答案取决于您是谁。如果您是 Linux 用户,并且不管理自己的系统,那么 FSSTND 可以确保如果您已经在另一台 Linux 机器上拥有经验,您将能够在您期望的位置找到程序。它还可以确保您可能拥有的任何文档都有意义。此外,如果您之前已经有一些 Unix 经验,那么 FSSTND 与您当前使用的内容不应有太大差异,但有一些例外。也许最重要的是,标准的制定使 Linux 达到了一定的成熟度,作者和商业应用程序开发人员认为他们可以支持。
如果您管理自己的机器,那么您将获得上述 FSSTND 的所有好处。如果您遇到问题,您也可能会对其他人为您提供支持的能力感到更加安全。此外,定期升级系统在理论上更容易。由于文件位置有一个公认的标准,软件包维护人员可以提供升级说明,这些说明不会在您的系统中留下额外的旧文件,占用宝贵的磁盘空间。FSSTND 还意味着,那些为您提供源代码包以供您自己编译和安装的人员会提供更多支持。例如,提供商知道在 Linux 机器上的哪个位置可以找到 sed 的可执行文件,并可以在其安装脚本或 Makefile 中使用它。
如果您运行大型网络,FSSTND 可能会减轻您的许多 NFS 难题,因为它专门解决了以前使 /usr 的共享实现不切实际的问题。如果您是发行商,那么您将受到 Linux FSSTND 的最大影响。您可能需要做一些额外的工作来确保您的发行版符合 FSSTND,但您的用户(以及您的业务)将从中受益。如果您的系统符合标准,则第三方附加软件包(以及您自己的软件包)将与您的系统平滑集成。当然,您的用户将获得上述所有好处,并且您的许多支持难题将得到缓解。您将受益于对 FSSTND 进行的所有讨论和思考,并避免自行设计文件系统结构时涉及的许多陷阱。如果您遵守 FSSTND,您还可以利用 FSSTND 设计的各种功能。例如,FSSTND 使包含除 / 和 /var 目录中的某些文件之外的所有内容的“live” CD-ROM 成为可能。如果您为 Linux 编写文档,FSSTND 使这项工作变得容易得多,这对 Linux 社区来说是有意义的。您不再需要担心一个发行版与另一个发行版上的锁文件的具体位置,也不必被迫编写仅对特定发行版的用户有用的文档。FSSTND 至少在一定程度上促成了最近 Linux 书籍出版的爆炸式增长。
如果您是开发人员,FSSTND 的存在大大降低了潜在问题的可能性。您可以知道重要系统二进制文件的位置,因此您可以从程序或 shell 脚本内部使用它们。支持用户也变得容易得多,因为在解决支持问题时,您不必担心这些二进制文件的位置等问题。如果您是需要与系统其余部分集成的程序的开发人员,FSSTND 可以确保您确定实现此目的的步骤。例如,访问串行端口的 kermit 等应用程序需要知道它们可以独占访问 TTY 设备。FSSTND 指定了一种通用的方法来执行此操作,以便所有符合标准的应用程序都可以协同工作。这样,您可以专注于为 Linux 制作更出色的软件,而不是担心如何检测和处理 Linux 风格的差异。Linux 社区对 FSSTND 的广泛接受对于标准和操作系统的成功至关重要。几乎每个现代发行版都符合 Linux FSSTND。如果您的实现至少不部分符合 FSSTND,那么它可能非常旧,或者您是自己构建的。FSSTND 本身包含一个旨在符合 FSSTND 的发行版列表。但是,有些发行版在 FSSTND 的实现中偷工减料是众所周知的。
这绝不意味着标准本身是完整的。仍然存在未解决的问题,例如与体系结构无关的脚本和数据文件 /usr/share 的组织。到目前为止,i386 一直是 Linux 的主要平台,因此不存在对此类文件进行标准化的需求。
Linux 快速移植到其他体系结构(MC680x0、Alpha、MIPS、PowerPC)表明,这个问题很快就需要处理。另一个正在讨论的问题是像 SVR4 中那样创建 /opt 目录。此类目录的目标是为大型商业或第三方软件包提供一个安装位置,而无需担心 FSSTND 对其他目录层次结构的要求。FSSTND 为 Linux 社区提供了出色的参考文档,并已被证明是 Linux 成熟的重要因素。随着 Linux 的不断发展,FSSTND 也将随之发展。
现在,我们已经了解了事情应该 如何,让我们看看现实世界。您将看到,这个概念在 Linux 上的实现并不完美,并且由于 Linux 一直吸引着倾向于相当固执己见的个人主义者,因此,例如,某些文件应该放在哪些目录中一直是用户争论的焦点。随着不同发行版的出现,混乱再次降临到我们身上。一些发行版将外部介质的挂载目录放在 / 目录中,另一些发行版放在 /mnt 中。基于 Red Hat 的发行版具有 /etc/sysconfig 子层次结构,用于有关输入和网络设备的配置文件。其他发行版根本没有这个目录,而是将相应的文件放在其他地方,甚至使用完全不同的机制来做同样的事情。一些发行版将 KDE 放在 /opt/ 中,另一些发行版放在 /usr 中。
但是,即使在给定的文件系统层次结构中,也存在不一致之处。例如,即使这从来不是 XFree86 组的意图,XFree86 实际上确实有自己的目录层次结构。
只要您自己编译程序,这些问题就不会显现出来。您可以使配置脚本或 Makefile 适应您的系统配置或您的偏好。但是,如果您安装像 RPM 这样的预编译软件包,情况就不同了。通常,这些软件包无法从一个文件系统层次结构适应到另一个文件系统层次结构。更糟糕的是:某些 RPM 甚至可能创建自己的层次结构。例如,如果您在 Mandrake 系统上安装来自 SuSE Linux 发行版的 KDE RPM,则二进制文件将放在 /opt/kde2/bin 中。因此它将无法工作,因为 Mandrake 期望它在 /usr/bin 中。当然,有办法规避这个问题,但目前的情况显然是站不住脚的。因此,所有主要的 Linux 发行商都加入了 Linux 标准库项目,该项目试图为 Linux 发行版创建通用标准。这并不容易,因为更改文件系统层次结构意味着发行商需要做大量工作,因此每个发行商都试图推行一种标准,使其尽可能保留自己的层次结构。LSB 还将包含文件系统层次结构标准项目(FHS,前身为 FSSTND)提出的建议。