在前面的章节中,我们研究了在文件级别操纵数据。在本章中,我们将考虑设备级别的数据。Linux在处理存储设备方面具有惊人的能力,无论是物理存储,如硬盘、网络存储,还是虚拟存储设备,如RAID(Redundant Array of Independent Disks,独立磁盘冗余阵列)和LVM(Logical Volume Manager,逻辑卷管理器)。
然而,由于这不是一本关于系统管理的书,我们不会试图深入探讨整个主题。我们将尝试介绍一些用于管理存储设备的概念和关键命令。
要执行本章中的练习,我们将使用USB闪存驱动器、USB硬盘驱动器和CD-RW光盘(适用于配备CD-ROM刻录机的系统)。
我们将查看以下命令:
mount
—— 挂载文件系统umount
—— 卸载文件系统parted
—— 分区操作程序mkfs
—— 创建文件系统fsck
—— 检查和修复文件系统dd
—— 转换和复制文件genisoimage
—— 创建ISO 9660映像文件wodim
—— 将数据写入光存储介质sha265sum
—— 计算并检查SHA256校验和第十五章:存储介质挂载和卸载存储设备查看已装载文件系统列表为什么卸载很重要确定设备名称创建新文件系统使用 parted
操作分区使用 mkfs
创建新文件系统测试和修复文件系统什么是 fsck
?将数据直接移入和移出设备创建CD-ROM映像创建CD-ROM的映像副本从文件集合创建图像任何其他名称的程序...写入CD-ROM映像直接挂载ISO映像清空可重写CD-ROM写入映像验证数据总结
Linux桌面的最新进展使桌面用户的存储设备管理变得极其容易。在大多数情况下,我们将一个设备连接到我们的系统上,它“就正常工作了”。在过去(比如2004年),这些事情必须手动完成。在非桌面系统(即服务器)上,这仍然是一个很大程度上手动的过程,因为服务器通常具有极端的(extreme)存储需求和复杂的(complex)配置要求。
管理存储设备的第一步是将设备连接到文件系统树。这个过程称为挂载(mounting),允许设备与操作系统交互。正如我们在【第2章】中回忆的那样,类Unix操作系统,如Linux,维护着一个文件系统树,其中设备连接在不同的点上。这与MS-DOS和Windows等其他操作系统形成鲜明对比,这些操作系统为每个设备维护单独的文件系统树(例如 C:\ 、D:\ 等)。
名为 /etc/fstab (“file system table,文件系统表”的缩写)的文件列出了在启动时要挂载的设备(通常是硬盘分区)。以下是早期Fedora系统中的 /etc/fstab 文件示例:
xxxxxxxxxx
LABEL=/12 / ext4 defaults 1 1
LABEL=/home /home ext4 defaults 1 2
LABEL=/boot /boot ext4 defaults 1 2
tmpfs /dev/shm tmpfs defaults 0 0
devpts /dev/pts devpts gid=5,mode=620 0 0
sysfs /sys sysfs defaults 0 0
proc /proc proc defaults 0 0
LABEL=SWAP-sda3 swap swap defaults 0 0
此示例文件中列出的大多数文件系统都是虚拟的,不适用于我们的讨论。就我们的目的而言,有趣的是前三个:
xxxxxxxxxx
LABEL=/12 / ext4 defaults 1 1
LABEL=/home /home ext4 defaults 1 2
LABEL=/boot /boot ext4 defaults 1 2
这些是硬盘分区。文件的每一行由六个字段组成,如下表所示:
字段 | 内容 | 解释 |
---|---|---|
1 | 设备 | 传统上,此字段包含与物理设备关联的设备文件的实际名称,例如 /dev/sda1 (第一个检测到的硬盘的第一个分区)。但是,对于今天的计算机,其中有许多可热插拔的设备(如USB驱动器),许多现代Linux发行版将设备与文本标签(text label)相关联。此标签(在格式化时添加到存储介质中)可以是简单的文本标签,也可以是随机生成的UUID(Universally Unique Identifier,通用唯一标识符)。当设备连接到系统时,操作系统会读取此标签。这样,无论将哪个设备文件分配给实际的物理设备,它仍然可以被正确识别。 |
2 | 挂载点 | 设备连接到文件系统树的目录。 |
3 | 文件系统 | Linux允许挂载多种类型的文件系统。大多数Linux系统使用称为第四扩展文件系统(Fourth Extended File System,ext4)的原生Linux文件系统,但支持许多其他文件系统,包括FAT16(msdos )、FAT32(vfat )、NTFS(NTFS )、CD-ROM(iso9660 )等。 |
4 | 选项 | 文件系统可以通过各种选项进行挂载。例如,可以将文件系统挂载为只读或阻止从中执行任何程序(可移动介质的一个有用的安全功能)。 |
5 | 频率 | 一个数字,指定是否以及何时使用转储命令备份文件系统。 |
6 | 顺序 | 一个数字,指定使用fsck命令检查文件系统的顺序。本章稍后将对此进行详细介绍。 |
mount
命令用于挂载文件系统。输入不带参数的命令将显示当前装载的文件系统列表:
xxxxxxxxxx
[me@linuxbox ~]$ mount
/dev/sda2 on / type ext4 (rw)
proc on /proc type proc (rw)
sysfs on /sys type sysfs (rw)
devpts on /dev/pts type devpts (rw,gid=5,mode=620)
/dev/sda5 on /home type ext4 (rw)
/dev/sda1 on /boot type ext4 (rw)
tmpfs on /dev/shm type tmpfs (rw)
none on /proc/sys/fs/binfmt_misc type binfmt_misc (rw)
sunrpc on /var/lib/nfs/rpc_pipefs type rpc_pipefs (rw)
fusectl on /sys/fs/fuse/connections type fusectl (rw)
/dev/sdd1 on /media/disk type vfat (rw,nosuid,nodev,noatime,uhelper=hal,uid=500,utf8,shortname=lower)
twin4:/musicbox on /misc/musicbox type nfs4 (rw,addr=192.168.1.4)
提示:Ubuntu用户会发现这个列表中充斥着由系统上安装的snap包创建的“循环(loop)”设备。要查看更清晰的列表,请尝试以下命令: mount | grep -v snap
列表的格式如下:
device on mount_point type file_system_type (options)
例如,第一行显示设备 /dev/sda2 作为根文件系统挂载,类型为 ext4 ,可读写(选项 rw )。此列表底部还有两个有趣的条目。倒数第二个条目显示了挂载在 /media/disk 上的读卡器中的2GB SD存储卡,最后一个条目是挂载在 /misc/musicbox 上的网络驱动器。
在我们的第一个实验中,我们将使用4GB的闪存驱动器。首先,让我们在插入驱动器之前看看Ubuntu 22.04系统:
xxxxxxxxxx
[me@linuxbox ~]$ mount | grep /dev/sd
/dev/sda2 on / type ext4 (rw,relatime,errors=remount-ro)
/dev/sda1 on /boot/efi type vfat (rw,relatime,fmask=0077,dmask=0077, codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro)
/dev/sdb1 on /home type ext4 (rw,relatime)
为了清楚起见,我们通过 grep
将输出管道化,仅在列表中列出 /dev/sd* 设备。我们可以看到这个系统有两个硬盘,/dev/sda 和 /dev/sdb 。/dev/sda 上有两个分区。它们是 /dev/sda1 和 /dev/sda2 ,而 /dev/sdb 只有一个分区 /dev/sdb1 。
与许多现代Linux发行版一样,此系统将在插入后尝试自动挂载闪存驱动器。插入驱动器后,我们会看到以下内容:
xxxxxxxxxx
[me@linuxbox ~]$ mount | grep /dev/sd
/dev/sda2 on / type ext4 (rw,relatime,errors=remount-ro)
/dev/sda1 on /boot/efi type vfat (rw,relatime,fmask=0077,dmask=0077,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro)
/dev/sdb1 on /home type ext4 (rw,relatime)
/dev/sdc on /media/me/C911-C314 type vfat (rw,nosuid,nodev,relatime, uid=1000,gid=1000,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,showexec,utf8,flush,errors=remount-ro)
插入驱动器后,我们看到与之前相同的列表,但有一个额外的条目。在列表末尾,我们看到闪存驱动器(在该系统上为设备 /dev/sdc )已挂载在 /media/me/C911-C314 上,类型为 vfat (也称为FAT32,一种与Windows兼容的文件系统)。为了我们的实验,我们对设备的名称感兴趣。当您自己进行此实验时,设备名称很可能会不同。
警告:在以下示例中,您必须密切关注系统上使用的实际设备名称,不要使用本文中使用的名称!
现在我们有了闪存驱动器的设备名称,让我们卸载该驱动器,并在文件系统树中的另一个位置重新装载它。为此,我们成为超级用户(使用适合我们系统的命令),并使用 umount
(注意拼写)命令卸载驱动器。
xxxxxxxxxx
[me@linuxbox ~]$ sudo -i
[sudo] password for me:
[root@linuxbox ~]# umount /dev/sdc
下一步是为磁盘创建一个新的挂载点(mount point)。挂载点只是文件系统树上某个位置的目录。这没什么特别的。它甚至不必是空目录,但如果你在非空目录上挂载设备,在卸载设备之前,你将无法看到目录的先前内容。为了我们的目的,我们将创建一个新目录。
xxxxxxxxxx
[root@linuxbox ~]# mkdir /mnt/flash
最后,我们将闪存驱动器装载到新的装载点。 -t
选项用于指定文件系统类型。
xxxxxxxxxx
[root@linuxbox ~]# mount -t vfat /dev/sdc /mnt/flash
之后,我们可以通过新的挂载点检查闪存驱动器的内容:
xxxxxxxxxx
[root@linuxbox ~]# cd /mnt/flash
[root@linuxbox cdrom]# ls
请注意,当我们尝试卸载驱动器时会发生什么:
xxxxxxxxxx
[root@linuxbox cdrom]# umount /dev/sdc
umount: /mnt/flash: device is busy
这是为什么?原因是,如果设备正被某人或某个进程使用,我们就无法卸载该设备。在这种情况下,我们将工作目录更改为闪存驱动器的装载点,这会导致设备繁忙。我们可以通过将工作目录更改为挂载点以外的其他目录来轻松解决这个问题:
xxxxxxxxxx
[root@linuxbox cdrom]# cd
[root@linuxbox ~]# umount /dev/sdc
现在设备已成功卸载。
如果您查看显示内存使用统计信息的 free
命令的输出,您将看到一个名为 buffers 的统计信息。计算机系统被设计得尽可能快。系统速度的障碍之一是设备速度慢。打印机就是一个很好的例子。按照计算机标准,即使是最快的打印机也极其缓慢。如果计算机必须停下来等待打印机完成打印,那么它的速度确实会非常慢。在PC的早期(多任务处理之前),这是一个真正的问题。如果你正在处理电子表格或文本文档,每次打印时电脑都会停止运行,无法使用。计算机会以打印机可以接受的最快速度将数据发送到打印机,但由于打印机打印速度不是很快,所以速度非常慢。打印机缓冲区的出现解决了这个问题,这是一种包含一些RAM存储器的设备,可以放置在计算机和打印机之间。有了打印机缓冲区,计算机会将打印机输出发送到缓冲区,并将其快速存储在快速RAM中,这样计算机就可以重新开始工作,而无需等待。同时,打印机缓冲区会以打印机可以接受的速度,将数据从缓冲区的内存缓慢地传送到打印机。
这种缓冲的想法在计算机中被广泛使用,以使它们更快。不要让偶尔向慢速设备读写数据的需要阻碍系统的速度。操作系统在实际必须与较慢的设备交互之前,尽可能长时间地将已从存储设备读取和将要写入存储设备的数据存储在内存中。例如,在Linux系统上,您会注意到,使用时间越长,系统似乎就会填满内存。这并不意味着Linux正在“使用”所有内存;这意味着Linux正在利用所有可用内存进行尽可能多的缓冲。
这种缓冲允许非常快速地完成对存储设备的写入,因为对物理设备的写入被推迟到未来的时间。与此同时,发往该设备的数据正在内存中堆积。操作系统会不时地将此数据写入物理设备。
卸载设备需要将所有剩余数据写入设备,以便安全删除。如果未先卸载设备就将其删除,则可能并非所有发往该设备的数据都已传输。在某些情况下,这些数据可能包括重要的目录更新,这将导致文件系统损坏,这是计算机上可能发生的最糟糕的事情之一。
有时很难确定设备的名称。在过去,这并不难。设备总是在同一个地方,它不会改变。类Unix系统就是这样。当Unix被开发出来时,“更换磁盘驱动器”涉及使用叉车从计算机房中取出洗衣机大小的设备。近年来,典型的桌面硬件配置变得相当动态,Linux已经进化到比其祖先更灵活。
在上面的例子中,我们利用了现代Linux桌面的“自动”(automagically)挂载设备的能力,然后在事后确定名称。但是,如果我们正在管理一个服务器或其他没有发生这种情况的环境呢?我们怎样才能弄清楚?
首先,让我们看看系统是如何命名设备的。如果我们列出 /dev 目录(所有设备所在的目录)的内容,我们可以看到有很多很多设备。
xxxxxxxxxx
[me@linuxbox ~]$ ls /dev
此列表的内容揭示了设备命名的一些模式。下表概述了其中一些模式:
范式 | 设备 |
---|---|
/dev/fd* | 软盘驱动器 |
/dev/hd* | 旧系统上的IDE(PATA)磁盘。这些系统上的主板包含两个IDE连接器或通道(channels),每个都有一根带有两个驱动器连接点的电缆。电缆上的第一个驱动器称为主(master)设备,第二个驱动器称为从(slave)设备。设备名称按顺序排列,/dev/hda 指第一个通道上的主设备,/dev/hdb 指第一个信道上的从设备;/dev/hdc 是第二个通道上的主设备,以此类推。尾随数字表示设备上的分区号。例如,/dev/hda1 表示系统上第一个硬盘驱动器上的第一个分区,而 /dev/hda 表示整个驱动器。 |
/dev/lp* | 打印机 |
/dev/sd* | SCSI磁盘。在现代Linux系统上,内核将所有类似磁盘的设备(包括PATA/SATA硬盘、闪存驱动器和USB大容量存储设备,如便携式音乐播放器和数码相机)视为SCSI磁盘。命名系统的其余部分与上述旧的 /dev/hd* 命名方案相似。 |
/dev/sr* | 光驱(CD/DVD读取器和刻录机) |
此外,我们经常看到符号链接,如 /dev/cdrom 、 /dev/dvd 和 /dev/floppy ,它们指向实际的设备文件,这是为了方便而提供的。
如果我们在一个不能自动挂载可移动设备的系统上工作,我们可以使用以下技术来确定可移动设备在连接时的命名方式。首先,启动 /var/log/messages 或 /var/log/syslog 文件的实时视图(您可能需要超级用户权限):
xxxxxxxxxx
[me@linuxbox ~]$ sudo tail -f /var/log/syslog
在基于systemd的现代系统上,使用此命令跟踪systemd日志:
xxxxxxxxxx
[me@linuxbox ~]$ sudo journalctl -f
将显示列表的最后几行,然后暂停。接下来,插入可拆卸设备。在这个例子中,我们将卸载并移除闪存驱动器,然后重新插入。内核几乎会立即注意到该设备并对其进行探测。
xxxxxxxxxx
Jul 25 13:15:07 ratel mtp-probe[21318]: checking bus 3, device 8: "/sys/devices/pci0000:00/0000:00:14.0/usb3/3-6"
Jul 25 13:15:07 ratel mtp-probe[21318]: bus: 3, device: 8 was not an MTP device
Jul 25 13:15:07 ratel mtp-probe[21321]: checking bus 3, device 8: "/sys/devices/pci0000:00/0000:00:14.0/usb3/3-6"
Jul 25 13:15:07 ratel mtp-probe[21321]: bus: 3, device: 8 was not an MTP device
Jul 25 13:15:08 ratel kernel: scsi 6:0:0:0: Direct-Access General UDisk 5.00 PQ: 0 ANSI: 2
Jul 25 13:15:08 ratel kernel: sd 6:0:0:0: Attached scsi generic sg3 type 0
Jul 25 13:15:08 ratel kernel: sd 6:0:0:0: [sdc] 7864320 512-byte logical blocks: (4.03 GB/3.75 GiB)
Jul 25 13:15:08 ratel kernel: sd 6:0:0:0: [sdc] Write Protect is off
Jul 25 13:15:08 ratel kernel: sd 6:0:0:0: [sdc] Mode Sense: 0b 00 00 08
Jul 25 13:15:08 ratel kernel: sd 6:0:0:0: [sdc] No Caching mode page found
Jul 25 13:15:08 ratel kernel: sd 6:0:0:0: [sdc] Assuming drive cache: write through
Jul 25 13:15:08 ratel kernel: sdc:
Jul 25 13:15:08 ratel kernel: sd 6:0:0:0: [sdc] Attached SCSI removable disk
显示再次暂停后,按 Ctrl-c 返回提示。输出中有趣的部分是对 [sdc]
的重复引用,这与我们对SCSI磁盘设备名称的期望相匹配。知道这一点,这两行变得特别有启发性:
xxxxxxxxxx
Jul 25 13:15:08 ratel kernel: sdc:
Jul 25 13:15:08 ratel kernel: sd 6:0:0:0: [sdc] Attached SCSI removable disk
提示:使用 tail -f /var/log/syslog
或 journalctl -f
技术是近实时查看系统运行情况的好方法。
还有一种方法可以确定设备名称(在Linux中总是有多种方法!)。我们可以使用 lsblk
命令。此命令列出了连接到系统的所有块设备,无论它们是否已安装。
假设我们已经卸载并删除了闪存驱动器,我们可以查看连接的块设备列表:
xxxxxxxxxx
[me@linuxbox ~]$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
sda 8:0 0 111.8G 0 disk
├─sda1 8:1 0 976M 0 part /boot/efi
│ /
└─sda3 8:3 0 14.9G 0 part [SWAP]
sdb 8:16 0 931.5G 0 disk
├─sdb1 8:17 0 922.2G 0 part /home
└─sdb2 8:18 0 9.3G 0 part
sr0 11:0 1 1024M 0 rom
接下来,我们将重新插入闪存驱动器并再次运行 lsblk
:
xxxxxxxxxx
[me@linuxbox ~]$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
sda 8:0 0 111.8G 0 disk
├─sda1 8:1 0 976M 0 part /boot/efi
│ /
└─sda3 8:3 0 14.9G 0 part [SWAP]
sdb 8:16 0 931.5G 0 disk
├─sdb1 8:17 0 922.2G 0 part /home
└─sdb2 8:18 0 9.3G 0 part
sdc 8:32 1 3.8G 0 disk
sr0 11:0 1 1024M 0 rom
我们现在看到一个新设备(sdc)已添加到列表中。只要设备仍物理连接到计算机并且计算机未重新启动,设备名称将保持不变。
有了我们的设备名称,我们就可以挂载闪存驱动器了。
xxxxxxxxxx
[me@linuxbox ~]$ sudo mount /dev/sdc /mnt/flash
[me@linuxbox ~]$ df
Filesystem 1K-blocks Used Available Use% Mounted on
tmpfs 1624184 2144 1622040 1% /run
/dev/sda2 98430196 45133696 48250332 49% /
tmpfs 8120908 0 8120908 0% /dev/shm
tmpfs 5120 4 5116 1% /run/lock
/dev/sda1 997456 6220 991236 1% /boot/efi
/dev/sdb1 950690656 585574576 316749944 65% /home
tmpfs 1624180 80 1624100 1% /run/user/120
tmpfs 1624180 192 1623988 1% /run/user/1000
/dev/sdc 3924444 4 3924440 1% /mnt/flash
假设我们有一个带有单个FAT32文件系统的外部USB硬盘,并希望将驱动器分为两个分区,一个是Linux本机文件系统(ext4),另一个是格式化为NTFS的分区,用于Windows系统。这涉及两个步骤:
警告!在下面的练习中,我们将格式化外部硬盘。使用不包含任何您关心的内容的驱动器,因为它将被擦除!同样,请务必为您的系统指定正确的设备名称,而不是文本中显示的名称。不注意此警告可能会导致您格式化(即擦除)错误的驱动器!
parted
操作分区parted
是一系列程序(包括命令行和图形)之一,它允许我们在非常低的级别上直接与类磁盘设备(如硬盘驱动器和闪存驱动器)进行交互。我们将连接驱动器并使用 lsblk
获取其名称:
xxxxxxxxxx
[me@linuxbox ~]$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
sda 8:0 0 111.8G 0 disk
├─sda1 8:1 0 976M 0 part /boot/efi
│ /
└─sda3 8:3 0 14.9G 0 part [SWAP]
sdb 8:16 0 931.5G 0 disk
├─sdb1 8:17 0 922.2G 0 part /home
└─sdb2 8:18 0 9.3G 0 part
sdd 8:32 0 232.9G 0 disk
└─sdd1 8:33 0 232.9G 0 part /media/me/USB_DISK
sr0 11:0 1 1024M 0 rom
如我们所见,外部USB硬盘已连接,名为 /dev/sdd ,其中包含一个名为 /dev/sdd1 的分区。
使用 parted
,我们可以在设备上编辑、删除和创建分区。要使用我们的硬盘,我们必须首先卸载它(如果需要),然后按如下方式调用 parted
程序:
xxxxxxxxxx
[me@linuxbox ~]$ sudo umount /dev/sdd1
[me@linuxbox ~]$ sudo parted /dev/sdd
请注意,我们必须根据整个设备来指定设备,而不是通过分区号。程序启动后,我们将看到以下提示:
xxxxxxxxxx
GNU Parted 3.4
Using /dev/sdd
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted)
输入 help
将显示可用命令的列表:
xxxxxxxxxx
(parted) help
align-check TYPE N check partition N for
TYPE(min|opt) alignment
help [COMMAND] print general help, or
help on COMMAND
mklabel,mktable LABEL-TYPE create a new disklabel
(partition table)
mkpart PART-TYPE [FS-TYPE] START END make a partition
name NUMBER NAME name partition NUMBER as
NAME
print [devices|free|list,all|NUMBER] display the partition
table, available devices,
free space, all found
partitions, or a
particular partition
quit exit program
rescue START END rescue a lost partition
near START and END
resizepart NUMBER END resize partition NUMBER
rm NUMBER delete partition NUMBER
select DEVICE choose the device to edit
disk_set FLAG STATE change the FLAG on
selected device
disk_toggle [FLAG] toggle the state of FLAG
on selected device
set NUMBER FLAG STATE change the FLAG on
partition NUMBER
toggle [NUMBER [FLAG]] toggle the state of FLAG
on partition NUMBER
unit UNIT set the default unit to
UNIT
version display the version number
and copyright information
of GNU Parted
我们要做的第一件事是检查现有的分区布局。我们通过输入 print
命令来打印设备的分区表:
x(parted) print
Model: WDC WD25 00BEVT-00A0RT0 (scsi)
Disk /dev/sdd: 250GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags:
Number Start End Size Type File system Flags
1 1049kB 250GB 250GB primary fat32 lba
我们可以看到,我们的磁盘在单个FAT32分区中有250 GB的空间。
要创建新分区,我们必须首先删除当前分区。这很容易用 rm
命令完成:
xxxxxxxxxx
(parted) rm 1
(parted) print
Model: WDC WD25 00BEVT-00A0RT0 (scsi)
Disk /dev/sdd: 250GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags:
Number Start End Size Type File system Flags
我们指定要删除的分区号,然后再次查看分区表,查看分区是否已消失。
接下来,我们将创建新的分区。我们使用 mkpart
命令执行此操作。
xxxxxxxxxx
(parted) mkpart
Partition type? primary/extended? primary
File system type? [ext2]? ext4
Start? 1
End? 120000
在这个磁盘上创建分区时(它有一个MBR,主引导记录样式的分区表),我们指定一个主分区或扩展分区,然后以默认的一兆字节增量指定分区的开始和结束。使用120000 MB的最终值会消耗驱动器上大约一半的可用空间。
接下来,我们将使用相同的技术创建第二个分区。
xxxxxxxxxx
(parted) mkpart
Partition type? primary/extended? primary
File system type? [ext2]? ntfs
Start? 120001
End? 240000
最后,我们查看分区表以查看结果:
xxxxxxxxxx
(parted) print
Model: WDC WD25 00BEVT-00A0RT0 (scsi)
Disk /dev/sdd: 250GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags:
Number Start End Size Type File system Flags
1 1049kB 120GB 120GB primary ext4 lba
2 120GB 240GB 120GB primary ntfs lba
现在我们的分区已经完成,我们可以退出 parted
程序了:
xxxxxxxxxx
(parted) quit
如果我们再次运行 lsblk
,我们可以看到我们的驱动器及其两个分区。
xxxxxxxxxx
[me@linuxbox ~]$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
sda 8:0 0 111.8G 0 disk
├─sda1 8:1 0 976M 0 part /boot/efi
│ /
└─sda3 8:3 0 14.9G 0 part [SWAP]
sdb 8:16 0 931.5G 0 disk
├─sdb1 8:17 0 922.2G 0 part /home
└─sdb2 8:18 0 9.3G 0 part
sdd 8:32 0 232.9G 0 disk
└─sdd1 8:33 0 232.9G 0 part
└─sdd2 8:50 0 111.8G 0 part
sr0 11:0 1 1024M 0 rom
mkfs
创建新文件系统完成分区编辑后,是时候在驱动器上创建(即格式化)新的文件系统了。为此,我们将使用 mkfs
(“make file system”的缩写),它可以创建各种格式的文件系统。要在驱动器上创建 ext4 文件系统,我们使用-t选项指定 ext4
文件系类型,后面是描述性卷标,以及包含要格式化的分区的设备名称。
xxxxxxxxxx
[me@linuxbox ~]$ sudo mkfs -t ext4 -L EXT4_Disk /dev/sdd1
mke2fs 1.46.5 (30-Dec-2021)
Creating filesystem with 29296640 4k blocks and 7331840 inodes
Filesystem UUID: 3365d135-d8d9-4b93-a57a-ec3567c8548a
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632,
2654208, 4096000, 7962624, 11239424, 20480000, 23887872
Allocating group tables: done
Writing inode tables: done
Creating journal (131072 blocks): done
Writing superblocks and filesystem accounting information: done
接下来,我们将进行NTFS分区。
xxxxxxxxxx
[me@linuxbox ~]$ sudo mkfs -t ntfs --quick -L NTFS_Disk /dev/sdd2
Cluster size has been automatically set to 4096 bytes.
Creating NTFS volume structures.
mkntfs completed successfully. Have a nice day.
我们再次指定文件系统类型、描述性卷标和设备。我们包含 --quick
选项来跳过坏块检查,因为这需要很长时间才能执行完。
请注意,不同的文件系统类型支持不同的选项。有关详细信息,请参阅 mkfs
手册页。
工作完成后,让我们拔下驱动器并重新连接,使系统自动装载驱动器。再次运行 lsblk
可以显示结果。
xxxxxxxxxx
[me@linuxbox ~]$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
sda 8:0 0 111.8G 0 disk
├─sda1 8:1 0 976M 0 part /boot/efi
│ /
└─sda3 8:3 0 14.9G 0 part [SWAP]
sdb 8:16 0 931.5G 0 disk
├─sdb1 8:17 0 922.2G 0 part /home
└─sdb2 8:18 0 9.3G 0 part
sdd 8:32 0 232.9G 0 disk
└─sdd1 8:33 0 232.9G 0 part /media/me/EXT4_Disk
└─sdd2 8:50 0 111.8G 0 part /media/me/NTFS_Disk
sr0 11:0 1 1024M 0 rom
正如我们所看到的,卷标用于在可移动存储设备自动挂载的 /media 目录中创建挂载点名称。
在我们之前对 /etc/fstab 文件的讨论中,我们在每行末尾看到了一些神秘的数字。每次系统启动时,它都会在挂载文件系统之前定期检查文件系统的完整性。这是由 fsck
程序(“file system check,文件系统检查”的缩写)完成的。每个 fstab 条目中的最后一个数字指定了检查设备的顺序。在前面的示例中,我们看到首先检查根文件系统,然后检查 home 文件系统和 boot 文件系统。最后一位数字为零的设备不会进行常规检查。
除了检查文件系统的完整性外,fsck
还可以根据损坏程度修复损坏的文件系统,成功程度各不相同。在类Unix文件系统中,恢复的文件部分被放置在 lost+found 目录中,该目录位于每个文件系统的根目录中。
要检查我们的 EXT4_Disk
分区(应该先卸载),我们可以执行以下操作:
xxxxxxxxxx
[me@linuxbox ~]$ sudo umount /dev/sdd1
[me@linuxbox ~]$ sudo fsck /dev/sdd1fsck from util-linux 2.37.2
e2fsck 1.46.5 (30-Dec-2021)
EXT4_Disk: clean, 11/7331840 files, 606693/29296640 blocks
如今,除非出现硬件问题,如磁盘驱动器故障,否则文件系统损坏的情况非常罕见。在大多数系统上,启动时检测到的文件系统损坏将导致系统停止,并指示您在继续之前运行 fsck
。
fsck
?在Unix文化中, fsck
这个词经常被用来代替一个流行词,它与该词共享三个字母。这尤其合适,因为如果你发现自己处于被迫运行 fsck
的情况下,你可能会说出上述单词。
虽然我们通常认为计算机上的数据是组织成文件的,但也可以将数据视为“原始”(row)形式。例如,如果我们查看磁盘驱动器,我们会看到它由大量“块”(blocks)数据组成,操作系统将其视为目录和文件。然而,如果我们可以将磁盘驱动器视为一个庞大的数据块集合,我们就可以执行有用的任务,例如克隆设备。
dd
程序执行此任务。它将数据块从一个地方复制到另一个地方。它使用了一种独特的语法(出于历史原因),通常是这样使用的:
dd if=input_file of=output_file [bs=block_size [count=blocks]]
警告! dd
命令非常强大。虽然它的名字来源于“数据定义”(data definition),但它有时也被称为“销毁磁盘”(destroy disk),因为用户经常误输入 if
或 of
规范 。在按下enter 键之前,请务必仔细检查您的输入和输出规格!
假设我们有两个大小相同的USB闪存驱动器,我们想将第一个驱动器精确复制到第二个驱动器。如果我们将两个驱动器都连接到计算机,并分别分配给设备 /dev/sdb 和 /dev/sdc ,我们可以通过以下方式将第一个驱动器上的所有内容复制到第二个驱动器:
xxxxxxxxxx
[me@linuxbox ~]$ sudo dd if=/dev/sdb of=/dev/sdc
或者,如果只有第一个设备连接到计算机,我们可以将其内容复制到普通文件中,以便以后还原或复制。
xxxxxxxxxx
[me@linuxbox ~]$ sudo dd if=/dev/sdb of=flash_drive.img
【FreeBSD手册中使用以下命令将操作系统映像文件写入U盘:】
xxxxxxxxxx
# dd if=FreeBSD-13.1-RELEASE-amd64-memstick.img of=/dev/da0 bs=1M conv=sync
写入可记录CD-ROM(CD-R或CD-RW)包括两个步骤:
如果我们想制作现有CD-ROM的ISO映像,我们可以使用 dd
从CD-ROM中读取所有数据块并将其复制到本地文件。假设我们有一张Ubuntu CD,我们想制作一个ISO文件,以后可以用来制作更多的副本。插入CD并确定其设备名称(我们假设为 /dev/cdrom)后,我们可以这样制作ISO文件:
xxxxxxxxxx
dd if=/dev/cdrom of=ubuntu.iso
此技术也适用于数据DVD,但不适用于音频CD,因为它们不使用文件系统进行存储。对于音频CD,请查看 cdrdao
命令。
要创建包含目录内容的ISO映像文件,我们使用 genisoimage
程序。为此,我们首先创建一个包含要包含在图像中的所有文件的目录,然后执行 genisoimage
命令来创建图像文件。例如,如果我们创建了一个名为 ~/cd-rom-files 的目录,并在其中填充了CD-ROM的文件,我们可以使用以下命令创建一个名称为 cd-rom.iso 的映像文件:
xxxxxxxxxx
genisoimage -o cd-rom.iso -R -J ~/cd-rom-files
-R
选项为Rock Ridge扩展添(Rock Ridge extensions)加元数据,允许使用长文件名和POSIX样式的文件权限。同样, -J
选项启用Joliet扩展名(Joliet extensions),这允许Windows使用长文件名。
如果你查看创建和刻录光盘和DVD等光学介质的在线教程,你会经常遇到两个名为 mkisofs
和 cdrecord
的程序。这些程序是Jörg Schilling编写的一个名为 cdrtools
的流行软件包的一部分。2006年夏天,Schilling先生对 cdrtools
包的一部分进行了许可证更改,在Linux社区的许多人看来,这造成了与GNU GPL的许可证不兼容。因此, cdrtools
项目的一个分支开始了,现在包括分别名为 wodim
和 genisoimage
的 cdrecord
和 mkisofs
的替换程序。
有了ISO映像文件后,我们可以将其刻录到光学介质上。我们将在下面讨论的大多数命令都可以应用于可记录的CD-ROM和DVD介质。
有一个技巧,我们可以在ISO映像仍在硬盘上时将其挂载,并将其视为已经在光学介质上。通过添加 -o loop
选项来挂载(以及所需的 -t iso9660
文件系统类型),我们可以像挂载设备一样挂载映像文件,并将其附加到文件系统树中:
xxxxxxxxxx
mkdir /mnt/iso_image
mount -t iso9660 -o loop image.iso /mnt/iso_image
在上面的示例中,我们创建了一个名为 /mnt/iso_image 的挂载点,然后在该挂载点挂载了映像文件 image.iso 。挂载映像后,可以将其视为真正的CD-ROM或DVD。记得在不再需要映像时卸载它。
可重写CD-RW介质需要擦除或清空(blanked)才能重新使用。为此,我们可以使用 wodim
,指定CD刻录机的设备名称和要执行的清空类型。wodim计划提供了几种类型。最简单(也是最快)的是“快速”(fast)类型。
xxxxxxxxxx
wodim dev=/dev/cdrw blank=fast
要写入映像,我们再次使用 wodim
,指定光学介质写入器设备的名称和映像文件的名称:
xxxxxxxxxx
wodim dev=/dev/cdrw image.iso
除了设备名称和图像文件外, wodim
还支持大量选项。两种常见的模式是 -v
用于详细输出, -dao
用于以光盘一次性(disc-at-once)模式写入光盘。如果我们准备光盘进行商业复制,应该使用这种模式。 wodim
的默认模式是 track-at-once
,这对于录制音乐曲目很有用。
当我们讨论ISO文件时,让我们看看如何验证我们下载的文件的完整性。通常,当我们下载一个大文件,如新的Linux安装映像时,我们会希望确保我们下载的映像文件是完整的,没有损坏。我们可以使用的一个工具是 sha256sum
,它是早期名为 md5sum
的程序的现代替代品。
有两种常见的方法可以做到这一点。让我们试试。假设我们想下载Linux Mint 22的安装映像。我们访问Linux Mint网站,获取 linuxmint-22-cinnamon-64bit.iso 文件。在那里,我们还下载了一个名为 sha256sum.txt 的校验和文件。当我们查看其内容时,我们会看到以下内容:
xxxxxxxxxx
[me@linuxbox ~]$ cat sha256sum.txt
7a04b54830004e945c1eda6ed6ec8c57ff4b249de4b331bd021a849694f29b8f *lin uxmint-22-cinnamon-64bit.iso
78a2438346cfe69a1779b0ac3fc05499f8dc7202959d597dd724a07475bc6930 *lin uxmint-22-mate-64bit.iso
55e917b99206187564029476f421b98f5a8a0b6e54c49ff6a4cb39dcfeb4bd80 *lin uxmint-22-xfce-64bit.iso
三行数据,包含一长串十六进制数字和可供下载的文件名,包括我们下载的ISO文件。十六进制数字字符串是校验和,是ISO文件的精确数学表示。这些数字的特殊之处在于,如果下载的ISO文件与原始文件相差一位,校验和将明显不同。我们将测试ISO文件,看看校验和是否匹配。
xxxxxxxxxx
[me@linuxbox ~]$ sha256sum -b linuxmint-22-cinnamon-64bit.iso
7a04b54830004e945c1eda6ed6ec8c57ff4b249de4b331bd021a849694f29b8f *lin uxmint-22-cinnamon-64bit.iso
-b
选项告诉 sha256sum
我们正在查看二进制文件而不是文本。正如我们所看到的,校验和与我们在 sha256sum.txt 中看到的校验和匹配。然而,以这种方式查看校验和有点乏味。我们检查文件的另一种方法是让 sha256sum
处理 sha256sum.txt 文件,将其校验和与列表中文件生成的校验和进行比较。我们可以这样运行 sha256sum
程序:
xxxxxxxxxx
[me@linuxbox ~]$ sha256sum -c --ignore-missing sha256sum.txt
linuxmint-22-cinnamon-64bit.iso: OK
-c
选项(“check”的缩写)调用此模式,而 --ignore-missing
选项告诉 sha256sum
不要抱怨我们没有下载的文件,即 linuxmint-22-mate-64bit.iso 和 linuxmint--22-xfce-64bit-iso 不存在。
在本章中,我们介绍了基本的存储管理任务。当然,还有更多。Linux支持大量的存储设备和文件系统方案。它还提供了许多与其他系统互操作的功能。