Top

D12:常见任务和基本工具之二

存储介质

本章主要学习如何处理设备级的数据。
本章涉及的命令有:
目录:

挂载和卸载存储设备

Linux桌面的最新进展使桌面用户极易管理存储设备,在大多数情况下,把设备连接到系统上它就可以正常工作了。但在服务器上,这仍然是个手动过程,因为服务器通常有极端的存储需求和复杂的配置要求。

管理存储设备的第一步是将设备连接到文件系统树。这个过程称为挂载(mounting),允许设备与操作系统交互。

/etc/fstab(fstab是file system table的缩写)列出了引导时要挂载的设备(通常是硬盘分区)。下面是早期Fedora系统中的一个例子:
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	
这里只讨论前三行。每行有六个段,每段的含义如下表所述:
段号 内容 说明
1 设备 传统上,此字段包含与物理设备关联的设备文件的实际名称,例如/dev/sda1(第一个检测到的硬盘的第一个分区)。
但当代计算机上,有许多可热插拔的设备(如USB驱动器),许多现代Linux发行版将设备与文件标签关联起来。
该标签(格式化后添加到存储介质中)可以是简单的文本标签,也可以是随机生成的UUID(Universally Unique Identifier,通用唯一标识符)。
当设备连接到系统是,操作系统会读取此标签。这样,无论哪个设备文件被分配给实际的物理设备,它仍然可以被正确识别。
2 挂载点 设备附加到文件系统树的目录。
3 文件系统类型 大多数本机Linux文件系统是第四扩展文件系统(Fourth Extended File System,ext4)。
还支持其他文件系统,比如FAT16(msdos)、FAT32(vfat)、NTFS、CD-ROM(iso9660)等。
4 选项 文件系统可以通过各种选项挂载。
例如,可以将文件系统挂载为只读,或防止任何程序从文件系统执行(这是可移动媒体的一个有用的安全功能能)。
5 频率 指定是否可以以及何时使用dump命令备份文件系统的单个数字。
6 顺序 指定使用fsck命令检查文件系统的顺序

查看已挂载的文件系统列表

mount命令可以用来挂载文件系统,如果此命令后面没有跟任何参数,则显示当前系统已经挂载的文件系统:
[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)		
显示结果的格式为:设备 on 挂载点 type 文件系统类型(选项)
比如,第一行显示设备/dev/sda2作为根系统挂载,类型为ext4,并且可读写(选项“rw”)。
倒数第二行显示的是挂载在/media/disk上的读卡器中的2GB SD存储卡;最后一行是挂载在/misc/musicbox上的网络驱动器。

第一个实验将使用CD-ROM。首先,在插入CD-ROM之前,系统是这样的:
[me@linuxbox ~]$ mount
/dev/mapper/VolGroup00-LogVol00 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/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)		
这是一个CentOS系统,该系统使用LVM(Logical Volume Manager,逻辑卷管理器)创建其根文件系统。
插入光盘后,内容变为:
[me@linuxbox ~]$ mount
/dev/mapper/VolGroup00-LogVol00 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/hda1 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)
/dev/sdc on /media/live-1.0.10-8 type iso9660 (ro,noexec,nosuid,nodev,uid=500)
		
结果中多出一行,说明CD-ROM(/dev/sdc)已经挂载到/media/live-1.0.10-8上了。
需要注意,音频CD与CD-ROM不同,它不包含文件系统,因此无法按照这个方法挂载。

接下来卸载光盘,并在文件系统树中的另一个位置重新挂载它。为此要先称为超级用户,并使用umount命令卸载光盘:
[me@linuxbox ~]$ su -
Password:
[root@linuxbox ~]# umount /dev/sdc
接下来为光盘创建一个新的挂载点。
[root@linuxbox ~]# mkdir /mnt/cdrom
最后将CD-ROM挂载到新的挂载点。-t选项用于指定文件系统类型:
[root@linuxbox ~]# mount -t iso9660 /dev/sdc /mnt/cdrom
然后就可以进到/mnt/cdrom目录中查看光盘里面的内容了。
如果没有退出光盘的挂载目录时,使用umount命令卸载光盘会失败并收到提示:
[root@linuxbox cdrom]# umount /dev/sdc
umount: /mnt/cdrom: device is busy

应及时卸载不用的设备

确定设备名称

/dev中保存所有设备的名称,设备命名模式如下表:
样式 设备
/dev/fd* 软盘设备
/dev/hd* 旧系统上的IDE(PATA)硬盘。
/dev/lp* 打印机
/dev/sd* SCSI磁盘(FreeBSD中使用/dev/da*)
当代Linux系统内核将所有类似磁盘的设备(如硬盘、U盘和移动硬盘、MP3和数码相机等)都视为SCSI磁盘。
插在第一个SATA口上的硬盘被命名为hda、第二个口上的为hdb,依次类推。后面跟数字表示第几个分区。
如/dev/sda1表示插在第一个SATA口上的磁盘的第一个分区。(FreeBSD中为/dev/da0p1)
/dev/sr* 光驱
此外,为了方便,常见一些符号链接,如/dev/cdrom、/dev/dvd、/dev/floppy等,它们指向实际的设备文件。

如果系统不能自动挂载可移动设备,可以通过以下方法来确定可移动设备在连接时的命名方式:
首先启动/var/log/messages或/var/log/syslog文件的实时视图(这可能需要超级用户权限) :
[me@linuxbox ~]$ sudo tail -f /var/log/messages
以上命令会显示文件的最后几行,并暂停下来。这也是实时监控系统动态的方法。
然后插入可移动设备,内核立即会在控制台上反馈设备信息:
Jul 23 10:07:53 linuxbox kernel: usb 3-2: new full speed USB device using uhci_hcd and address 2
Jul 23 10:07:53 linuxbox kernel: usb 3-2: configuration #1 chosen from 1 choice
Jul 23 10:07:53 linuxbox kernel: scsi3 : SCSI emulation for USB Mass Storage devices
Jul 23 10:07:58 linuxbox kernel: scsi scan: INQUIRY result too short (5), using 36
Jul 23 10:07:58 linuxbox kernel: scsi 3:0:0:0: Direct-Access Easy Disk 1.00 PQ: 0 ANSI: 2
Jul 23 10:07:59 linuxbox kernel: sd 3:0:0:0: [sdb] 31263 512-byte hardware sectors (16 MB)
Jul 23 10:07:59 linuxbox kernel: sd 3:0:0:0: [sdb] Write Protect is off
Jul 23 10:07:59 linuxbox kernel: sd 3:0:0:0: [sdb] Assuming drive cache: write through
Jul 23 10:07:59 linuxbox kernel: sd 3:0:0:0: [sdb] 31263 512-byte hardware sectors (16 MB)
Jul 23 10:07:59 linuxbox kernel: sd 3:0:0:0: [sdb] Write Protect is off
Jul 23 10:07:59 linuxbox kernel: sd 3:0:0:0: [sdb] Assuming drive cache: write through
Jul 23 10:07:59 linuxbox kernel: sdb: sdb1
Jul 23 10:07:59 linuxbox kernel: sd 3:0:0:0: [sdb] Attached SCSI removable disk
Jul 23 10:07:59 linuxbox kernel: sd 3:0:0:0: Attached scsi generic sg3 type 0		
当显示再次暂停时,按Ctrl-c退回提示符状态。我们感兴趣的部分是对[sdb]的重复引用,它符合我们对SCSI磁盘设备名称的期望。
下面两行值得注意:
Jul 23 10:07:59 linuxbox kernel: sdb: sdb1
Jul 23 10:07:59 linuxbox kernel: sd 3:0:0:0: [sdb] Attached SCSI removable disk		
这告诉我们设备名称是/dev/sdb,第一个分区是/dev/adb1。

拿到设备名称后,可以挂载闪存驱动器:
[me@linuxbox ~]$ sudo mkdir /mnt/flash
[me@linuxbox ~]$ sudo mount /dev/sdb1 /mnt/flash
[me@linuxbox ~]$ df
Filesystem   1K-blocks      Used Available Use% Mounted on
/dev/sda2     15115452   5186944   9775164  35% /
/dev/sda5     59631908  31777376  24776480  57% /home
/dev/sda1       147764     17277    122858  13% /boot
tmpfs           776808         0    776808   0% /dev/shm
/dev/sdb1        15560         0     15560   0% /mnt/flash		
若不改变设备与计算机的物理连接,且计算机未重新启动,设备名称将保持不变。

创建新文件系统

要使用Linux本机文件系统格式化闪存,需要两个步骤:

使用fdisk操作分区

要使用fdisk操作分区,必须先卸载掉目标设备:
[me@linuxbox ~]$ sudo umount /dev/sdb1
[me@linuxbox ~]$ sudo fdisk /dev/sdb
fdisk启动后可以看到以下提示:
Command (m for help):
输入m将显示帮助信息:
Command action
   a    toggle a bootable flag                   切换可引导标志
   b    edit bsd disklabel                       编辑bsd磁盘标签
   c    toggle the dos compatibility flag        切换dos兼容性标志
   d    delete a partition                       删除一个分区
   l    list known partition types               列出已知分区类型
   m    print this menu                          显示此帮助菜单
   n    add a new partition                      添加一个新分区
   o    create a new empty DOS partition table   创建一个新的空DOS分区表
   p    print the partition table                显示分区表
   q    quit without saving changes              退出,不保存
   s    create a new empty Sun disklabel         创建一个新的空Sun磁盘标签
   t    change a partition's system id           变更分区的系统id
   u    change display/entry units               变更显示/输入单位
   v    verify the partition table               检查分区表
   w    write table to disk and exit             将分区表写入磁盘并退出
   x    extra functionality (experts only)   	 额外功能(仅限专家)
		
首先要做的是检查现有的分区情况。输入p,然后回车:
Command (m for help): p

Disk /dev/sdb: 16 MB, 16006656 bytes
1 heads, 31 sectors/track, 1008 cylinders
Units = cylinders of 31 * 512 = 15872 bytes

   Device Boot Start  End Blocks Id System
/dev/sdb1          2 1008  15608+ b W95 FAT32		
本例中有一个16MB的设备,它有一个独立的分区(1),使用设备上可用的1008个柱面中1006个柱面。
该分区被标识为Windows95 FAT32分区。以下演示如何将其改为Linux分区。

首先找出用于标识Linux分区的ID。
使用l命令可以查看所有能识别的分区格式,找到Linux的分区类型为83。
接下来使用t命令设置新ID:
Command (m for help): t
Selected partition 1
Hex code (type L to list codes): 83
Changed system type of partition 1 to 83 (Linux)		
完成更改后,需要将修改的分区表写入设备并退出:
Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.

WARNING: If you have created or modified any DOS 6.x
partitions, please see the fdisk manual page for additional
information.
Syncing disks.
[me@linuxbox ~]$		
如果决定保持设备不变,可以输入q退出而不保存。

使用mkfs创建新文件系统

分区编辑完成后,需要在闪存上创建一个新的文件系统。使用mkfs(make file system的缩写)可以创建各种格式的文件系统。
[me@linuxbox ~]$ sudo mkfs -t ext4 /dev/sdb1
mke2fs 2.23.2 (12-Jul-2011)
Filesystem label=
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
3904 inodes, 15608 blocks
780 blocks (5.00%) reserved for the super user
First data block=1
Maximum filesystem blocks=15990784
2 block groups
8192 blocks per group, 8192 fragments per group
1952 inodes per group
Superblock backups stored on blocks:
8193
Writing inode tables: done
Creating journal (1024 blocks): done
Writing superblocks and filesystem accounting information: done
This filesystem will be automatically checked every 34 mounts or
180 days, whichever comes first. Use tune2fs -c or -i to override.
[me@linuxbox ~]$		
当选择ext4文件系统时,程序将显示大量信息。
要将设备重新格式化为其原始FAT32文件系统的话,可指定文件系统类型为vfat:
[me@linuxbox ~]$ sudo mkfs -t vfat /dev/sdb1
这种分区和格式化过程可以在系统中添加其他存储设备的任何时候使用。

测试和修复文件系统

fsck(file system check的简写)命令负责检查文件系统的完整性。
在/etc/fstab文件中,每一行的末尾数字指定设备的检查顺序。如果最后以为是零,则该设备不会被例行检查。
除了检查文件系统的完整性,fsck还可以修复损坏的文件系统,修复的成功率取决于损坏的程度。
在类Unix的文件系统中,文件的恢复部分放在每个文件系统根目录下的lost+found目录中。

fsck用法如下:
[me@linuxbox ~]$ sudo fsck /dev/sdb1
fsck 1.40.8 (13-Mar-2016)
e2fsck 1.40.8 (13-Mar-2016)
/dev/sdb1: clean, 11/3904 files, 1661/15608 blocks
文件系统不易损坏,除非出现硬件故障。大多数系统上,启动时检测到文件系统损坏时会导致系统停止,并指示在继续之前运行fsck
此时,经常会忍不住要说出另外一个跟它长得很像的单词。

直接在设备之间移动数据

通常认为计算机上的数据被组织成文件,但也有可能认为数据是原始(raw)的形式。可以将整个磁盘驱动器视为一个大的数据块集合,可以执行例如克隆设备这样的任务。
dd程序执行此任务。它将数据块从一个地方复制到另一个地方。
它使用一种独特的语法,通常是这样的:
dd if=input_file of=output_file [bs=block_size [count=blocks]]
严重警告:dd命令非常强大。
虽然它的名字来源于”data definition“(数据定义),但有时被称为”destroy disk“。因为用户经常错误地键入if或of。
在按回车之前,请务必仔细检查输入和输出的规格。

如果有两个大小相同的U盘,通过以下命令可以将第一个U盘上的数据复制到第二个U盘上:
dd if=/dev/sdb of=/dev/sdc
或者,也可以使用以下命令将设备上的数据复制到文件中:
dd if=/dev/sdb of=flash_drive.img

创建CD-ROM镜像

写入可擦写CD-ROM(CD-R或CD-RW)包括两个步骤:

创建CD-ROM的镜像拷贝

以下命令演示从一张Ubuntu光盘制作iso文件,假设光盘设备为/dev/cdrom:
dd if=/dev/cdrom of=ubuntu.iso
此方法适用于数据DVD,但不适用于音频CD,因为音频CD不使用文件系统存储。对于音频CD,可使用cdrdao命令

从一个文件的集合创建镜像

使用genisoimage程序创建包含目录内容的ISO映像文件。
首先要创建一个目录,其中包含要包含在映像中的所有文件,然后执行genisoimage命令:
genisoimage -o cd-rom.iso -R -J ~/cd-rom-files
-R选项为Rock Ridge扩展添加元数据,允许使用长文件名和POSIX风格的文件权限;
-J选项启用了Joliet扩展,允许使用Windows长文件名。

写CD-ROM镜像

有了映像文件之后,可以将其刻录到光学介质上。

直接挂载ISO镜像

mount命令中使用-o loop选项可以将映像文件直接挂载:
mkdir /mnt/iso_image
mount -t iso9660 -o loop image.iso /mnt/iso_image

清空一个可写的CD-ROM

可重写CD-RW介质在重新使用前需要擦除或清除。
wodim dev=/dev/cdrw blank=fast
blank选项指定擦除类型,fast是最简单也是最快的类型。

写镜像

以下命令用于写入光学介质:
wodim dev=/dev/cdrw image.iso
除了设备名称和图像文件外,wodim还支持大量选项。两种常见的方法是-v表示详细输出、-dao表示以disc-at-once模式写入光盘,此模式多用于制作商业光盘。
wodim的默认模式是track-at-once,这对录制音乐曲目很有用。

扩展知识——映像校验

通常,验证下载的ISO映像的完整性很有用。大多数情况下ISO映像的分发服务器也会提供校验和文件。
最常见的校验和生成方法是使用md5sum程序:
md5sum image.iso
34e354760f9bb7fbf85c96f6a3f94ece image.iso
将此结果与发布者提供的md5sum值对比就可以知道是否一致。

除了检查下载文件的完整性,还可以用它来验证新写入的光学介质。先计算映像文件的校验和,再计算媒体的校验和。
md5sum /dev/cdrom
34e354760f9bb7fbf85c96f6a3f94ece /dev/cdrom
以下例子检查DVD读取器/dev/dvd中映像文件dvd-image.iso文件和光盘的完整性:
md5sum dvd-image.iso; dd if=/dev/dvd bs=2048 cont=$(( $(stat -c "%s" dvd-image.iso)/2048 )) | md5sum