为什么我们需要在 Linux 上挂载?

Gre*_*eso 73 mount devices

我了解 Linux 中的挂载是什么,我了解设备文件。但是我不明白为什么我们需要挂载。

例如,如this question接受答案中所述,使用以下命令:

mount /dev/cdrom /media/cdrom
Run Code Online (Sandbox Code Playgroud)

我们正在安装 CDROM 设备/media/cdrom并最终能够使用以下命令访问 CDROM 的文件

ls /media/cdrom
Run Code Online (Sandbox Code Playgroud)

这将列出 CDROM 的内容。

为什么不完全跳过安装,并执行以下操作?

ls /dev/cdrom
Run Code Online (Sandbox Code Playgroud)

并已列出 CDROM 的内容。我希望答案之一是:“这就是 Linux 的设计方式”。但如果是这样,那为什么要这样设计呢?为什么不/dev/cdrom直接访问目录?安装的真正目的是什么?

Ehr*_*ryk 72

一个原因是块级访问比ls能够使用的级别要低一些。/dev/cdrom,或者dev/sda1可能分别是您的 CD ROM 驱动器和硬盘驱动器的分区 1,但它们没有实现 ISO 9660 / ext4 - 它们只是指向那些称为Device Files 的设备的 RAW 指针。

mount 决定的一件事是如何使用原始访问 - 哪些文件系统逻辑/驱动程序/内核模块将管理读/写,或转换ls /mnt/cdrom为需要读取的块,以及如何解释这些块的内容块变成像file.txt.

其他时候,这种低级访问就足够了;我刚刚读取和写入串行端口、USB 设备、tty 终端和其他相对简单的设备。我永远不会尝试从 /dev/sda1 手动读/写来编辑文本文件,因为我基本上必须重新实现 ext4 逻辑,其中可能包括:查找文件 inode,找到存储块,读取完整块,进行更改,写入完整块,然后更新 inode(可能),或者将这些全部写入日志 - 太困难了。

亲眼看到这一点的一种方法就是尝试一下:

[root@ArchHP dev]# cd /dev/sda1
bash: cd: /dev/sda1: Not a directory
Run Code Online (Sandbox Code Playgroud)

/dev是一个目录,你可以cdls你喜欢的。/dev/sda1不是目录;它是一种特殊类型的文件,内核提供该文件作为该设备的“句柄”。

有关更深入的处理,请参阅设备文件上的维基百科条目

  • @Ehryk(3 条评论)在典型的 Linux 系统中唯一的预防措施是文件系统权限 - 换句话说,您必须使用 root 帐户写入设备文件。如果你这样做了,你可以“cat >/dev/sda1”尽情享受,Linux 不会阻止你。(不用说,这样做会完全破坏文件系统。) (6认同)
  • @psusi 你不能在 Windows 95 上这样做,是的。但它在 MS DOS 和 Windows NT 上存在(并且隐藏得很深)。您的现代基于 NT 的 Windows 当然允许您随意挂载和卸载分区(甚至可以挂载到其他分区上的文件夹中,甚至可以同时挂载到多个文件夹中)- 默认情况下,它通常只是将所有未知分区挂载到驱动器号。您还可以通过使用它的完整路径(非常类似于 unix 方式)来访问设备而无需安装它,但前提是它没有被锁定 - 如果它当前已安装,当然是这样。 (5认同)
  • 我掩盖了一些细节,因为我认为如果您开始写入存储在 /dev/sda1 上的任何数据,就会发生**坏事**,因此我认为有一些预防措施或抽象可能会阻止您从覆盖的东西。但总而言之,如果您确切地知道如何以及在何处写入磁盘,您可以通过`/dev/sda1` 手动完成。请注意,某些工具确实直接与原始磁盘交互,例如 `swapon/swapoff` 和 `dd`。 (4认同)
  • 再补充一点,挂载会初始化文件系统,从而激活一整层对用户透明的输入/输出操作的自动处理(例如在 RAM 中缓存文件、将操作排队、保存打开文件的状态)等等)。这就是为什么您还必须正确卸载文件系统以避免损坏(或至少同步它)。挂载存在于所有常用平台上,而不仅仅是 linux。如果安装是由桌面环境(KDE 或 gnome)自动处理的,它就像在 MS Windows 中一样隐藏。 (4认同)
  • @Luaan & psusi Psusi 拥有它的权利。但是对于几乎所有的意图和目的,Win32 API 调用者的效果基本上是相同的。(为了符合 Posix,甚至有一个装载语义的模拟。)Win9x 实际上确实有装载的概念,因为它仍然运行在 DOS 之上。FAT 支持作为本地处理程序内置到 DOS 中,有点类似于 NT 内核处理它的方式。但是必须安装 CDROM 和网络文件系统。(记住 CD 的 MSCDEX。它提供了 ISO/RockRidge 文件系统处理程序并将其安装在驱动器号上)。 (3认同)
  • 因此,换句话说,您是说,挂载有助于通过“/dev/sda1”将设备的内容作为常规文件系统访问。但是,如果我们想直接读/写输入/输出,那么我们可以通过`/dev/sda1`来完成,它会转移到输出吗? (2认同)
  • 挂载过程允许您将设备的内容作为文件系统访问;它完成了与找出文件系统、加载内核模块或它需要的代码以及促进该交互层的创建有关的任何魔术。一旦到位,mount 就完成了它的工作,但文件系统代码仍然存在以提供文件系统。 (2认同)
  • @Luaan,不,我说的是 NT 内核(所有版本)。你不能要求任何类似挂载的东西,你只需打开,例如,\Devices\PhysicalDisk0\Parittion1\foo.txt,如果尚未绑定到设备,则会触发搜索合适的文件系统。盘符概念在win32 api级别实现为符号链接,例如\DosDevices\C:->\Devices\Physicaldisk0\Partition1。分配驱动器号/创建该符号链接不会在任何地方激活文件系统;它只是在 win32 命名空间中创建一个指向磁盘设备的名称。 (2认同)

小智 20

基本上,简单地说,操作系统需要知道如何访问该设备上的文件。

mount 不仅是“让您访问文件”,它还告诉操作系统驱动器具有的文件系统,它是只读还是读/写访问等。

/dev/cdrom是一个低级设备,操作系统功能不知道如何访问它们......想象你在其中放置了一个奇怪格式的 cdrom(甚至是音频 cd),如何ls知道哪些文件(如果有的话)在那里没有先“安装”它的光盘?

请注意,这在许多操作系统中自动发生(甚至在某些发行版和图形界面上的 Linux)中,但这并不意味着其他操作系统不会“安装”驱动器。


gar*_*Red 8

为了一致性

假设您在系统的第一个硬盘驱动器上有一些分区。例如,/dev/sda2。您后来认为该驱动器不够大,因此您购买了第二个并将其添加到系统中。突然之间,那变成了,/dev/sda而您当前的驱动器变成了/dev/sdb。您的分区现在是/dev/sdb2.

使用您提议的系统,您必须更改访问旧分区上数据的所有脚本、应用程序、设置等,以反映名称的这种更改。

但是,挂载允许您仍然为这个重命名的驱动器使用相同的挂载点。您必须编辑/etc/fstab以告诉您的系统(例如)/media/backup现在/dev/sdb2改为,但这只是一次编辑。

请注意,现代系统更容易。它们没有将设备引用为/dev/sda2/dev/sdb2,而是具有UUIDS,它们看起来类似于c5845b43-fe98-499a-bf31-4eccae14261b或可以被赋予更友好的标签,例如backup在安装时可用于引用设备。这样,在添加新设备时设备名称不会改变,这使得管理更加简单:

# mount LABEL="backup" /media/backup
Run Code Online (Sandbox Code Playgroud)

为了安全

通过要求安装设备,管理员可以控制对设备的访问。设备可以在卸载时移除,但不能在使用时移除(除非您想遭受数据丢失)。如果您是(曾经)Windows 用户,还记得通知区域中的绿色小图标告诉您可以安全移除 U 盘吗?那是 Windows 为您安装和卸载棒。所以这个原理不仅仅是一个 Unix/Linux 的原理。


小智 7

我称之为历史原因。并不是说其他​​答案是错误的,而是这个故事还有更多内容。

比较 Windows:Windows 开始时是一个单计算机、单用户操作系统。那台计算机可能只有一个软驱和一个硬盘,没有网络连接,没有 USB,什么都没有。(Windows 3.11 具有本机网络功能;Windows 3.1 没有。)

Windows 诞生的那种设置非常简单,没有必要花哨:每次都自动安装所有东西(所有两个设备),没有(不是)很多事情可能会出错。

相比之下,Unix 从一开始就被设计为在具有多个用户的服务器网络上运行。

Unix 设计决策之一是,无论物理磁盘分布在多少台计算机上,无论哪种磁盘,也无论数十台计算机中的哪台,文件系统都应该作为一个统一的实体出现在最终用户面前。用户将从中访问它。用户文件的逻辑路径将保持不变,即使这些文件的物理位置在一夜之间发生了变化,例如由于服务器维护。

他们从存储这些文件的物理设备中抽象出逻辑文件系统、文件路径。假设服务器A通常托管/home,但服务器A需要维护:只需卸载服务器A并在/home上安装备份服务器B,除了管理员之外没有人会注意到。
(与为不同物理设备赋予不同名称的 Windows 约定不同 - C:、D: 等 - 这违背了 Unix 所追求的透明度。)

在那种环境下,你不能随意地把所有东西都装上,

在大型网络中,个别磁盘和计算机经常无法使用。管理员需要能够说明在何时何地安装了什么,例如,在另一台计算机透明地接管托管相同文件的同时,对一台计算机进行受控关闭。

所以从历史的角度来看,这就是为什么:Windows 和 Unix 来自不同的背景。如果您愿意,您可以将其称为文化差异:

  • Unix 诞生于管理员需要控制挂载的环境中;在网络上的数十个存储设备中,管理员必须决定在何时何地安装哪些设备。
  • Windows 诞生于没有管理员和只有两个存储设备的环境中,用户可能知道他们的文件是在软盘上还是在硬盘上。
  • (当然,Linux 是作为单机操作系统而诞生的,但它也从一开始就明确设计为在家用计算机上尽可能地模仿 Unix。)

最近,操作系统之间的距离越来越近:

  • Linux 增加了更多的单机、单用户的东西(比如自动挂载);因为它经常用于单机设置。
  • Windows 增加了更多的安全性、网络、多用户支持等;随着网络变得越来越普遍,微软也开始为服务器制作操作系统。

但仍然很容易说这两者是不同传统的结果。

  • 不仅如此。这些设备是文件系统驱动程序(可能还有其他系统软件)使用的低级抽象。Unix 是为操作系统程序员设计的操作系统。例如,那些文件系统驱动程序的程序员。这就是为什么这些低级抽象暴露给用户的原因。 (2认同)

hil*_*red 5

目前的安排有几个优点。它们可以分为块特殊文件的优点和挂载点的优点。

特殊文件是代表设备的文件。构建 unix 的理念之一是一切都是文件。这让很多事情变得简单,例如用户交互只是在 tty 设备上读写文件,这是一个字符特殊文件。同样,检查坏块、分区或格式化磁盘只是文件操作。磁盘是 mfm、ide、scsi、fiberchanel 还是其他类型的磁盘并不重要,它只是一个文件。

但另一方面,您可能不想处理整个磁盘或仅对文件进行分区,而且在许多情况下,文件数量超过磁盘容量。所以我们有挂载点。挂载点允许您将整个磁盘(或分区)放在目录中。在我的 Slackware 时代,一个大小合适的硬盘只有几百 MB,通常将 CD 用作 /usr,将硬盘用作 /、/usr/local 和交换。或者您可以将 / 放在一个驱动器上,将 /home 放在另一个驱动器上。

现在我注意到您提到将 CD 安装在 /media/cdrom 上,这对于只有一个 cdrom 驱动器的计算机来说很方便,但是如果您有多个 cdrom 呢?你应该在哪里安装第二个?还是第三个?还是第十五?您当然可以使用 /media/cdrom2 等。或者您可以将它挂载到 /src/samba/resources/windows-install 或 /var/www 或任何有意义的地方。

  • 我怀疑语义用法后来作为“在目录系统和指向设备的原始文件指针之间放置一些代码”的绝对必要性的有用副产品,因为使用 cd/ls/nano/everything else 比 raw 容易得多写道:`dd if=/file of=/dev/sda2 bs=4096 skip=382765832 count=84756`,更不用说相关的inode/FAT/journal更新了。 (3认同)
  • 我的第一台计算机在 2 个 8" 软盘上运行 cp/m。它根本不支持子目录。每个磁盘一个目录。路径看起来像 b:name.ext。语义命名的想法已经建立。甚至磁带系统使用文件名。UNIX 已经拒绝了挂载点的驱动器号的想法。顺便说一句,@Ehryk,你知道你不仅可以在 Windows 中而且可以在 dos 中将驱动器挂载到目录上吗?我是在 MS-DOS 5 上做到的.此外,当我在寻找手册页时,我不想记住它在哪台计算机上,更不用说哪个驱动器了。 (2认同)

rei*_*ost 5

问题标题问: 为什么我们需要在Linux上挂载?

解释这个问题的一种方法是:为什么我们需要发出明确的mount命令来使文件系统在 Linux 上可用?

答案是:我们没有。

您不需要显式挂载文件系统,您可以安排它自动完成,Linux 发行版已经为大多数设备执行了此操作,就像 Windows 和 Mac 一样。

所以这可能不是你想问的。

第二种解释:为什么我们有时需要发出显式mount命令才能使文件系统在 Linux 上可用? 为什么不让操作系统总是为我们做这件事,而对用户隐藏起来呢?

这是我在问题文本中读到的问题,当你问:

为什么不完全跳过安装,并执行以下操作

ls /dev/cdrom
Run Code Online (Sandbox Code Playgroud)

是否列出了 CD-ROM 的内容?

大概,您的意思是:为什么不让该命令执行操作

ls /media/cdrom
Run Code Online (Sandbox Code Playgroud)

现在呢?

那么,在这种情况下,/dev/cdrom将是一个目录树,而不是一个设备文件。所以你真正的问题似乎是:为什么首先要有一个设备文件?

我想为已经给出的答案添加一个答案。

为什么用户可以看到设备文件?

每当您使用 CD-ROM 或任何其他存储文件的设备时,都会使用一个软件将 CD-ROM 上的内容解释为文件目录树。每当您使用ls或任何其他类型的命令或应用程序访问 CD-ROM 上的文件时都会调用它。该软件是用于将文件写入 CD-ROM 的特定文件系统的文件系统驱动程序。每当您在文件系统上列出、读取或写入文件时,该软件的工作就是确保在相关设备上执行相应的低级读取和写入操作。每当您mount使用文件系统时,您都在告诉系统该设备使用哪个文件系统驱动程序。您是否明确地使用mount命令,或者让操作系统自动完成,这将需要完成,当然文件系统驱动程序软件首先需要在那里。

文件系统驱动程序如何工作?答案是:它通过读取和写入设备文件来实现。为什么?答案,正如您已经说过的:Unix 就是这样设计的。在 Unix 中,设备文件是设备常见的低级抽象。特定设备的真正特定于设备的软件(设备驱动程序)应该在设备上实现打开、关闭、读取和写入作为对设备文件的操作。这样,更高级别的软件(例如文件系统驱动程序)就不需要了解单个设备的内部工作原理了。低级设备驱动程序和文件系统驱动程序可以由不同的人分别编写,只要他们同意一种通用的相互接口方式,这就是设备文件的用途。

所以文件系统驱动程序需要设备文件。

但是为什么我们普通用户可以看到设备文件?答案是 Unix 是为操作系统程序员设计的。它旨在允许其用户编写设备驱动程序和文件系统驱动程序。事实上,这就是他们的写作方式。

对于 Linux 也是如此:您可以编写自己的文件系统驱动程序(或设备驱动程序),安装它,然后使用它。它使 Linux(或任何其他 Unix 变体)易于扩展(这实际上是 Linux 诞生的原因):当市场上出现一些新硬件时,或者设计了一种新的、更智能的方式来实现文件系统时,有人可以编写代码来支持它,使其工作,并将其贡献给 Linux。

设备文件使这更容易。