文章目录
1. 前言
在日常的运维工作当中,对 Linux 系统磁盘进行分区是非常常见的一种操作。一般来说,不管是使用 fdisk 工具还是 parted 工具,大体上的步骤是差不多的,都是需要先挂盘,然后对目标磁盘进行分区并格式化为指定的文件系统类型,最后创建挂载点并进行挂载。
在写这篇博客之前,也曾看过其他关于磁盘分区方面的文章,基本上照着操作就能实现简单的磁盘分区。不过,关于 parted 工具,我发现好多文章都将 mkpart primary
理解为是创建一个主分区,其实不然。大家可以在创建完分区以后执行 print
看一下分区的信息,在 gpt
分区下,primary
其实只是分区的 Name
,而不是分区的 Type
;只有在 msdos
(可以理解为就是 MBR 分区)分区下,才会区分主分区、扩展分区和逻辑分区,这个时候的 mkpart primary
才是真正创建了一个主分区。
本文结合了 fdisk 和 parted 两种常用的磁盘分区工具进行阐述,文章内容会涉及到两种工具的异同、MBR 分区与 GPT 分区的区别、如何实现分区对齐和精确分区,以及使用过程中的一些小问题。如有不当之处,欢迎指正,以便及时纠错。
2. 使用 fdisk 与 parted 进行磁盘分区
2.1. fdisk 与 parted 的异同
在 Linux 系统中,fdisk 几乎是最常用的一种磁盘分区工具,使用起来也非常简单。但是由于受到 MBR 分区表的限制,fdisk 工具只能给容量小于 2TB 的磁盘进行分区。
当然,parted 工具同样也可以对容量小于 2TB 的磁盘进行分区。但是当磁盘的容量超过 2TB 时,则只能使用 parted 工具进行磁盘分区了,并且还需要将磁盘设置为 GPT 格式。关于 MBR 与 GPT 格式的说明,且看下文。
2.2. 使用 fdisk 进行磁盘分区
关于 fdisk 的简单说明
Tip1
:使用 fdisk 查看目标磁盘的信息。
[root@ora12 ~]# fdisk -l /dev/sdc
Disk /dev/sdc: 2469.6 GB, 2469606195200 bytes, 4823449600 sectors //不同参考系下对磁盘容量的表示方法。
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes //逻辑扇区与物理扇区大小(对于后面理解分区对齐有一定的辅助意义)。
I/O size (minimum/optimal): 512 bytes / 512 bytes
Tip2
:使用 fdisk 进行分区时常用的参数解析。
Command (m for help): m
Command action
a toggle a bootable flag
b edit bsd disklabel
c toggle the dos compatibility flag
d delete a partition //根据分区号删除指定的分区。
g create a new empty GPT partition table
G create an IRIX (SGI) partition table
l list known partition types
m print this menu
n add a new partition //新建一个磁盘分区。
o create a new empty DOS partition table
p print the partition table //打印出当前的磁盘分区信息。
q quit without saving changes //退出且不保存配置信息。
s create a new empty Sun disklabel
t change a partition's system id //修改分区的类型(默认是标准分区,设置 “8e” 代表为 LVM 分区)。
u change display/entry units
v verify the partition table
w write table to disk and exit //保存配置信息并退出。
x extra functionality (experts only)
使用 fdisk 进行分区
注意事项1:
对于 MBR 分区来说,最多支持创建4个主分区(primary);如果一块磁盘需要创建超过4个以上的分区,那么至少要创建一个扩展分区(extended),然后基于扩展分区创建逻辑分区!
Step1
:创建两个分区(其中分区1为标准分区,容量为 100GB;分区2为 LVM 分区,将剩余容量全部分配给分区2)。
[root@ora12 ~]# fdisk /dev/sdb
Welcome to fdisk (util-linux 2.23.2).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
Device does not contain a recognized partition table
Building a new DOS disklabel with disk identifier 0x899a1c95.
Command (m for help): n //此处填写 “n” 表示新建一个分区。
Partition type:
p primary (0 primary, 0 extended, 4 free)
e extended
Select (default p): //此处默认为 primary(主分区)。
Using default response p
Partition number (1-4, default 1): //此处为分区编号(默认从1开始依次序递增)。
First sector (2048-419430399, default 2048): //分区1扇区的起始位置。
Using default value 2048
Last sector, +sectors or +size{K,M,G} (2048-419430399, default 419430399): +100G //分区1扇区的结束位置(通过扇区的起始位置与结束位置,可以计算出分区的容量;也可以通过 “+100G” 这种方式直接指定分区的容量大小)。
Partition 1 of type Linux and of size 100 GiB is set
Command (m for help): n //新建分区。
Partition type:
p primary (1 primary, 0 extended, 3 free)
e extended
Select (default p): //指定为主分区。
Using default response p
Partition number (2-4, default 2): //分区编号为2。
First sector (209717248-419430399, default 209717248):
Using default value 209717248
Last sector, +sectors or +size{K,M,G} (209717248-419430399, default 419430399): //表示将剩余空间全部分配给分区2。
Using default value 419430399
Partition 2 of type Linux and of size 100 GiB is set
Command (m for help): t //修改分区类型。
Partition number (1,2, default 2): //指定要修改的目标分区(默认为最近创建的分区,即分区2)。
Hex code (type L to list all codes): 8e // “8e” 代表 LVM 分区。
Changed type of partition 'Linux' to 'Linux LVM'
Command (m for help): p //打印出当前所有的分区信息。
Disk /dev/sdb: 214.7 GB, 214748364800 bytes, 419430400 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: dos
Disk identifier: 0x899a1c95
Device Boot Start End Blocks Id System
/dev/sdb1 2048 209717247 104857600 83 Linux //sdb1 为标准分区,容量为 100GB。
/dev/sdb2 209717248 419430399 104856576 8e Linux LVM //sdb1 为 LVM 分区,容量为 100GB。
Command (m for help): w //保存配置信息并退出。
The partition table has been altered!
Calling ioctl() to re-read partition table.
Syncing disks.
Step2
:更新内核的磁盘分区表信息。
[root@ora12 ~]# partprobe
Step3
:查询 “/dev/sdb” 的分区信息。
[root@ora12 ~]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 100G 0 disk
├─sda1 8:1 0 500M 0 part /boot
└─sda2 8:2 0 99.5G 0 part
├─centos-root 253:0 0 91.5G 0 lvm /
└─centos-swap 253:1 0 8G 0 lvm [SWAP]
sdb 8:16 0 200G 0 disk
├─sdb1 8:17 0 100G 0 part
└─sdb2 8:18 0 100G 0 part
sdc 8:32 0 2.3T 0 disk
[root@ora12 ~]# fdisk -l /dev/sdb
Disk /dev/sdb: 214.7 GB, 214748364800 bytes, 419430400 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: dos
Disk identifier: 0x899a1c95
Device Boot Start End Blocks Id System
/dev/sdb1 2048 209717247 104857600 83 Linux
/dev/sdb2 209717248 419430399 104856576 8e Linux LVM
Step4
:格式化分区。
[root@ora12 ~]# mkfs -t ext4 /dev/sdb1 //通过 “-t” 指定要将分区格式化为哪种文件系统类型。
[root@ora12 ~]# date && mkfs.ext4 /dev/sdb2 && date //对于较大的磁盘分区,可以通过 “date” 来计算整个格式化完成所需要的大致时间。
Step5
:将分区挂载到文件系统。
[root@ora12 ~]# mkdir -p /test_dir/{sdb1_dir,sdb2_dir} //创建两个目录作为挂载点。
[root@ora12 ~]# ls -l /test_dir/
total 0
drwxr-xr-x 2 root root 6 Jul 9 00:09 sdb1_dir
drwxr-xr-x 2 root root 6 Jul 9 00:09 sdb2_dir
[root@ora12 ~]# blkid /dev/sdb2 //查询 “/dev/sdb2” 所对应的 Block ID。
/dev/sdb2: UUID="6f29e755-07b4-4375-a9dc-690d49ceccb7" TYPE="ext4"
[root@ora12 ~]# echo "/dev/sdb1 /test_dir/sdb1_dir ext4 defaults 0 0" >> /etc/fstab //设置自动挂载,支持直接以分区进行挂载。
[root@ora12 ~]# echo "UUID=6f29e755-07b4-4375-a9dc-690d49ceccb7 /test_dir/sdb2_dir ext4 defaults 0 0" >> /etc/fstab //设置自动挂载,也支持直接以分区的 UUID 进行挂载(建议使用 UUID 方式)。
[root@ora12 ~]# mount -a //执行挂载并检查挂载结果。
[root@ora12 ~]# df -lh |grep sdb
/dev/sdb1 99G 61M 94G 1% /test_dir/sdb1_dir
/dev/sdb2 99G 61M 94G 1% /test_dir/sdb2_dir
2.3. 使用 parted 进行磁盘分区
关于 parted 的简单说明
Tip1
:使用 parted 进行分区时常用的参数解析。
[root@ora12 ~]# parted /dev/sdc
GNU Parted 3.1
Using /dev/sdc
Welcome to GNU Parted! Type 'help' to view a list of commands.
(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
2.3.1. 使用 parted 交互式进行磁盘分区
使用 parted 创建 MSDOS 分区
Step1
:使用 parted 创建3个主分区和3个逻辑分区。
[root@ora12 ~]# parted /dev/sdc
GNU Parted 3.1
Using /dev/sdc
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) mklabel msdos //表示将磁盘设置为 msdos 格式。
(parted) mkpart primary //表示将即将创建的这个分区指定为主分区。
File system type? [ext2]? ext4 //指定文件系统类型(实验中出现过设置了 ext4 但没有生效的现象,并建议在挂载时还是需要单独再进行格式化的)。
Start? 1MiB //设置分区的起始位置(以 1MiB 为开始位置是为了实现分区对齐)。
End? 102400MiB //设置分区的结束位置(以 102400MiB 为结束位置是为了精准创建一个 100G 的分区,后面使用 lsblk 可以看到分区容量为 100G)。
(parted) mkpart primary
File system type? [ext2]? ext4
Start? 102401MiB
End? 204800MiB
(parted) mkpart primary
File system type? [ext2]? ext4
Start? 204801MiB
End? 307200MiB
(parted) mkpart extended //在 msdos 格式下,最多只能创建4个主分区,所以只能将最后一个分区创建为扩展分区。
Start? 307201MiB
End? 100% //100% 代表将剩下的容量全部分配给扩展分区。
(parted) mkpart logic 307202MiB 409600MiB //创建逻辑分区
(parted) mkpart logic 409601MiB 512000MiB
(parted) mkpart logic 512001MiB -1 //“-1” 代表将剩下的容量全部分配给此逻辑分区。
(parted) quit
Information: You may need to update /etc/fstab.
Step2
:查看已分区信息。
[root@ora12 ~]# parted -s /dev/sdc print
Model: VMware Virtual disk (scsi)
Disk /dev/sdc: 2470GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags:
Number Start End Size Type File system Flags
1 1049kB 107GB 107GB primary
2 107GB 215GB 107GB primary
3 215GB 322GB 107GB primary
4 322GB 2470GB 2147GB extended lba
5 322GB 429GB 107GB logical
6 429GB 537GB 107GB logical
7 537GB 2470GB 1933GB logical
[root@ora12 ~]# lsblk |grep sdc
sdc 8:32 0 2.3T 0 disk
├─sdc1 8:33 0 100G 0 part //可以很直观的看到除了 sdc7 分区,其余每个分区的大小均为 100G。
├─sdc2 8:34 0 100G 0 part
├─sdc3 8:35 0 100G 0 part
├─sdc4 8:36 0 1K 0 part
├─sdc5 8:37 0 100G 0 part
├─sdc6 8:38 0 100G 0 part
└─sdc7 8:39 0 1.8T 0 part
Step3
:创建挂载点并格式化上述分区进行挂载。
[root@ora12 ~]# for i in {1,2,3,5,6,7};do mkdir -p /msdos/dir$i;done //批量创建挂载点。
[root@ora12 ~]# for i in {1,2,3,5,6,7};do mkfs.ext4 /dev/sdc$i;done //批量格式化分区。
[root@ora12 ~]# for i in {1,2,3,5,6,7};do mount /dev/sdc$i /msdos/dir$i;done //批量进行挂载。
Step4
:检查挂载结果。
[root@ora12 ~]# df -lh |grep sdc
/dev/sdc1 99G 61M 94G 1% /msdos/dir1
/dev/sdc2 99G 61M 94G 1% /msdos/dir2
/dev/sdc3 99G 61M 94G 1% /msdos/dir3
/dev/sdc5 99G 61M 94G 1% /msdos/dir5
/dev/sdc6 99G 61M 94G 1% /msdos/dir6
/dev/sdc7 1.8T 77M 1.7T 1% /msdos/dir7
使用 parted 创建 GPT 分区
Step1
:使用 parted 创建5个主分区。
[root@ora12 ~]# parted /dev/sdc
GNU Parted 3.1
Using /dev/sdc
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) mklabel gpt //表示将磁盘设置为 gpt 格式。
(parted) mkpart part1 //这里 mkpart 后面跟的是分区的 Name(很多人在这里依然写 primary,但这个时候 primary 仅代表分区名称,而不是指定为主分区)。
File system type? [ext2]? ext4
Start? 1MiB
End? 102400MiB
(parted) mkpart part2
File system type? [ext2]? ext4
Start? 102401MiB
End? 204800MiB
(parted) mkpart part3
File system type? [ext2]? ext4
Start? 204801MiB
End? 307200MiB
(parted) mkpart part4
File system type? [ext2]? ext4
Start? 307201MiB
End? 409600MiB
(parted) mkpart part5
File system type? [ext2]? ext4 //可以很直观的看到,在 gpt 格式下,不会受到4个主分区数的限制(创建了 part1 -- part5 5个分区)。
Start? 409601MiB
End? 100%
Step2
:关于挂载的操作可以参考前面的内容,此处略。
2.3.2. 使用 parted 非交互式进行磁盘分区
使用 parted 创建 MSDOS 分区
[root@ora12 ~]# parted -s /dev/sdc mklabel msdos mkpart primary 1MiB 102400MiB
[root@ora12 ~]# parted -s /dev/sdc mkpart primary 102401MiB 204800MiB
[root@ora12 ~]# parted -s /dev/sdc mkpart primary 204801MiB 307200MiB
[root@ora12 ~]# parted -s /dev/sdc mkpart extended 307201MiB 100% //在非交互式创建时,不支持以 “-1” 表示将剩余空间全部分配。
[root@ora12 ~]# parted -s /dev/sdc mkpart logic 307202MiB 409600MiB
[root@ora12 ~]# parted -s /dev/sdc mkpart logic 409601MiB 512000MiB
[root@ora12 ~]# parted -s /dev/sdc mkpart logic 512001MiB 100%
[root@ora12 ~]# parted -s /dev/sdc print
Model: VMware Virtual disk (scsi)
Disk /dev/sdc: 2470GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags:
Number Start End Size Type File system Flags
1 1049kB 107GB 107GB primary ext4
2 107GB 215GB 107GB primary ext4
3 215GB 322GB 107GB primary ext4
4 322GB 2470GB 2147GB extended lba
5 322GB 429GB 107GB logical ext4
6 429GB 537GB 107GB logical ext4
7 537GB 2470GB 1933GB logical ext4
[root@ora12 ~]# lsblk |grep sdc
sdc 8:32 0 2.3T 0 disk
├─sdc1 8:33 0 100G 0 part
├─sdc2 8:34 0 100G 0 part
├─sdc3 8:35 0 100G 0 part
├─sdc4 8:36 0 1K 0 part
├─sdc5 8:37 0 100G 0 part
├─sdc6 8:38 0 100G 0 part
└─sdc7 8:39 0 1.8T 0 part
使用 parted 创建 GPT 分区
[root@ora12 ~]# parted -s /dev/sdc mklabel gpt mkpart part1 1MiB 102400MiB
[root@ora12 ~]# parted -s /dev/sdc mkpart part2 102401MiB 204800MiB
[root@ora12 ~]# parted -s /dev/sdc mkpart part3 204801MiB 307200MiB
[root@ora12 ~]# parted -s /dev/sdc mkpart part4 307201MiB 409600MiB
[root@ora12 ~]# parted -s /dev/sdc mkpart part5 409601MiB 100%
[root@ora12 ~]# parted -s /dev/sdc print
Model: VMware Virtual disk (scsi)
Disk /dev/sdc: 2470GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:
Number Start End Size File system Name Flags
1 1049kB 107GB 107GB ext4 part1
2 107GB 215GB 107GB ext4 part2
3 215GB 322GB 107GB ext4 part3
4 322GB 429GB 107GB part4
5 429GB 2470GB 2040GB ext4 part5
[root@ora12 ~]# lsblk |grep sdc
sdc 8:32 0 2.3T 0 disk
├─sdc1 8:33 0 100G 0 part
├─sdc2 8:34 0 100G 0 part
├─sdc3 8:35 0 100G 0 part
├─sdc4 8:36 0 100G 0 part
└─sdc5 8:37 0 1.9T 0 part
3. MBR 分区与 GPT 分区的区别
在讲述这个问题之前,首先我们需要明白分区究竟是干嘛的?以笔记本电脑为例,假设配置了一块 500GB 的磁盘,我们在安装 Windows 系统时一般会将其划分成一个用于安装系统的 C盘
和一个专门用于存放个人数据的 D盘
,其实这里的 C盘和 D盘就是两个分区,只不过我们习惯性会去说电脑上有两块盘。同理,Linux 系统里面的磁盘进行分区,也是为了将其挂载到不同的目录下(挂载点),从而让用户可以在不同的目录下存放不同的数据文件。
所以,分区说白了就是在物理磁盘上划出一块块区域,并将这些区域映射(或者说挂载)到指定的目录下,可以让用户自定义每个分区的容量,并且根据自己的规划将不同的数据文件放到不同的目录中,彼此之间互不干扰。
而由于底层实现物理磁盘寻址与索引的数据结构不同,导致了在 MBR 格式和 GPT 格式下,能够创建的分区数量以及分区的类型也是不同的,下面将进行一个简单的介绍。
MBR:Master Boot Record(主引导记录)磁盘分区简化结构图
因为 MBR 扇区中用于记录磁盘分区表信息的区域只有 64 Bytes,而每 16 Bytes 用于一个分区的标识,所以对于 MBR 分区最多只能有4个主分区;如果需要创建4个以上的分区,则至少要创建一个扩展分区,进而创建逻辑分区。
对于 EBR 扇区,其用于记录磁盘分区表信息的区域也是 64 Bytes,同样也是每 16 Bytes 用于一个分区的标识。其中第一组的 16 Bytes 用于指向自身的引导扇区;第二组的 16 Bytes 用于指向下一个逻辑分区的 EBR 扇区(如果没有其它逻辑扇区,则全置为0);后两组的 32 Bytes 暂时未使用。
GPT:GUID Partition Table(全局唯一标识分区表) 磁盘分区简化结构图
MBR 分区与 GPT 分区的异同
- 从分区数量上来说,MBR 分区最多支持4个主分区,如果需要划分4个以上的分区,则至少需要创建一个扩展分区,继而创建逻辑分区。而 GPT 分区则不区分主分区、扩展分区和逻辑分区,并且支持的分区数量足够满足生产测试需要(看过其他博主的帖子,有说理论上分区数量是无限制的,也有说在 Windows 下最多分128个分区,博主没有去深究这块儿;一般来说磁盘空间大于 2TB 且分区数量比较多我就会选择使用 GPT 分区了)。
- 从分区容量上来说,MBR 分区最大支持的分区容量为 2TB,超过 2TB 进行分区时还是会以 2TB 进行计算;而 GPT 分区则没有这个限制,因此一般磁盘容量超过 2TB 以后,都会将磁盘设置为 GPT 格式。
- 从分区安全性来说,由于 GPT 格式的分区表会有备份,并且有相应的校验算法,因此,会比 MBR 格式的分区更加安全。
4. 如何实现分区对齐
其实这个章节我原本想要表达的意思是如何实现精准分区,举个简单的例子,一块 2TB 的磁盘,我想创建一个大小为 100GB 的分区,但是往往我们在分区的时候,明明计算的是 100GB,但是在分区完成以后,通过 lsblk 等命令去查看分区大小时会发现总是差那么一点儿,对于有强迫症的人来说,这个看起来就很难受。
在原本说这个话题的时候,又想到了之前遇到过的一个问题,叫做磁盘分区没有 4K 对齐。所以,这个章节我会将自己了解到的一些关于分区对齐和如何实现精准分区的心得分享给大家。当然,有不正确的地方欢迎朋友们指正哈。
我们先来看这张图片:(sdb1 分区未对齐、sdc1 分区是对齐的)
通过下面这条语句,我们可以判断一个磁盘分区是否对齐:
parted /dev/sdc align-check optimal 1 //数字1代表分区的编号,返回结果为 aligned 表示分区是对齐的。
首先,我们要明白的是,磁盘分区如果不对齐,会导致数据在读取写入时触发一些多余的动作,从而降低了磁盘的读写性能。这里可以参考分区4K对齐那些事,你想知道的都在这里,个人认为写得非常好。简单来说,就是所划出的分区没有完整的将物理扇区和逻辑扇区进行对齐,会导致上层数据在落盘时,明明一个物理扇区可以一次性写入,但由于没有对齐,可能会将数据分散到多个物理扇区中去,这样会产生多余的 I/O,以及增加对磁盘地址空间映射管理的开销,这个就是我上面说的一些多余的动作。
经过进一步测试,我发现:
如果我们在分区时使用 MiB 作为计算单位,无论是使用 fdisk 工具还是使用 parted 工具,所得到的分区都是对齐的,并且,最终得到的分区大小和我们计算出来的也是保持一致的,具体可以看上图中的 sdc1 和 sdc2 的效果。
这里就会涉及到以 MiB 与 MB 作为不同的计算单位所产生的不同效果,会对应到我们是以 1024 还是以 1000 来进行单位换算的。实际上,使用 MiB 单位就是以标准的二进制进行计算的,而使用 MB 则是以十进制进行计算的。很显然,使用二进制计算的 MiB 单位会更加符合计算机处理数据的标准,这也是为什么使用 MiB 作为单位进行分区时,分区既是对齐的,又是精确的。
另外,我们自己在购买磁盘时也会发现,磁盘上标出的容量是 3.2TB,但在系统中认到的磁盘空间会小于这个数值,原因就是磁盘厂家是以 1000 进行换算的,而系统内部是以 1024 进行换算的。
5. 总结
在日常的运维工作中,一般来说只要会简单地去使用 fdisk 和 parted 工具进行磁盘分区、格式化分区并进行挂载就可以了。就我自己而言,我用的最多的还是 fdisk 工具,对于大容量的磁盘很多时候都是直接作为裸磁盘去使用的。
这篇文章说来涉及到的东西还是比较多的,只是在原理性上还不够有深度,一方面是自己并非从事底层系统研究的,另一方面也没有那么多的时间去研究。不过,如果以后脑子不好使了,忘记了一些概念和命令,还是可以通过这篇文章来温习一下。