此读书笔记比较主要记录文件系统的相关操作。
基本上Linux最主要的文件系统为EXT2,该文件系统内的信息主要有:
- superblock:记录次文件系统的整体信息,包括inode/block的总量、使用量、剩余量以及文件系统的格式与相关信息等。
- inode:记录文件的属性,一个文件占用一个inode,同时记录此文件的数据所在的block号码。每个inode大小固定为128bytes。
- block:实际记录文件的内容,若文件太大时,会占用多个block。目录的block则记录该目录下面文件名与其inode号码的对照表。支持的block大小有1KB、2KB及4KB
磁盘与目录的容量
磁盘的整体数据是在superblock块中,但是每个个别文件的容量则在inode当中记载,常用来显示磁盘使用量的两个命令
df: 列出文件系统的整体磁盘使用量
du: 评估文件系统的磁盘使用量(常用于评估目录所占容量)
$ df [-ahikHTm] [目录或文件名]
参数:
-a: 列出所有的文件系统,包括系统特有的/proc(/proc挂载在内存中,不会占用磁盘空间)等文件系统;
-k: 以KB的容量显示各文件系统
-m: 以MB的容量显示各文件系统
-h:以人们较易阅读的GB、MB、KB等格式自行显示
-H: 以M=1000K 替换M=1024K 的进位方式
-T: 连同该分区的文件系统名称也列出(例如ext3)
-i: 不用硬盘容量,而以inode的数量显示
df主要读取的数据几乎都是针对整个文件系统,因此读取的范围只要是在super block内的信息,所以这个命令显示结果的速度非常快速。
$ du [-ahskm] 文件或者目录名称
参数:
-a 列出所有的文件与目录容量,因为默认仅统计目录的文件量而已
-h 以人们较易读的容量显示
-s 列出总量,而不列出每个个别的目录占用容量
-S 不包括子目录下的总计
-k 以KB列出容量显示
-m 以MB列出容量显示
du会直接查找文件系统的所有文件数据
连接文件: ln
在linux下的连接文件有两种:一种是类似Windows上的快捷方式,可以让你快速连接到目标文件或目录。另外一种则是通过文件系统的inode连接来产生新文件名,而不是产生新文件,这种称为硬链接(hard link)。
hard link(硬连接和实际连接)
- 每个文件都会占用一个inode,文件的内容由inode的记录来指向。
- 想要读取文件,必须要经过目录记录的文件名来指向到正确的inode号码才能读取。
- 文件名与目录有关,而文件内容则与inode有关,而hard link就是在某个目录下新建一个文件名连接到某inode号码的关联记录。
vagrant@vagrant-ubuntu-trusty-64:~$ cd /tmp
vagrant@vagrant-ubuntu-trusty-64:/tmp$ touch tes
vagrant@vagrant-ubuntu-trusty-64:/tmp$ ln test test1
vagrant@vagrant-ubuntu-trusty-64:/tmp$ ll -i test test1
62273 -rw-rw-r-- 2 vagrant vagrant 0 Dec 17 12:39 test
62273 -rw-rw-r-- 2 vagrant vagrant 0 Dec 17 12:39 test1
可以看到两个文件的inode号码是一致的,他们的文件权限属性完全一样,而连接数变为了2。
硬连接最大的好处就是安全,如果你将任何一个文件名删除,其实inode与block都是存在的。此时可以通过另外一个文件名来读取到正确的文件数据,不论你使用哪个文件名来编辑,最终的结果都会写到相同的inode与block中,因此均能进行数据的修改。
一般来说,使用hard link设置连接文件时,磁盘的空间和inode的数目都不会改变,hard link只是在某个目录下的block多写一个关联数据而已,既不会增加inode也不会耗用block数量(除非当你在block增加多一个关联数据时刚好磁盘满了,就可能需要增加多一个block来记录文件名关联性,而导致磁盘空间的变化)。
硬连接的限制:
- 不能跨文件系统
- 不能连接到目录,因为如果使用hard link连接到目录,连接的数据需要连同被连接目录下面的所有数据都建立连接,会造成环境相当大的复杂度,因此对于目录暂时不支持
symbolic link(符号连接,也即快捷方式)
symbolic link就是创建一个独立的文件,而这个文件会让数据的读取指向它链接的那个文件的文件名,由于只是利用文件作为指向的操作,所以当源文件被删除后,symbolic link的文件会找不到源文件而导致无法打开。
vagrant@vagrant-ubuntu-trusty-64:/tmp$ ln -s test test2
vagrant@vagrant-ubuntu-trusty-64:/tmp$ ll -i test test2
62273 -rw-rw-r-- 2 vagrant vagrant 0 Dec 17 12:39 test
62275 lrwxrwxrwx 1 vagrant vagrant 4 Dec 17 13:07 test2 -> test
两个文件指向不同的inode号码,连接文件的重要内容就是它会写上目标文件的文件名,因为箭头右边的文件是 4 Byte,所以连接文件的大小为 4 byte。
由symbolic link所创建的文件为一个独立的新的文件,所以会占用掉inode与block。
修改symbolic link文件时,会改动到源文件。
$ ln [-sf] 源文件 目标文件
参数:
-s: 如果不加任何参数进行连接,那就是hard link,至于-s就是symbolic link
-f: 如果目标文件存在时,主动将目标文件直接删掉再重建。
关于目录的连接数
当以hard link进行文件的连接时,文件的连接数会增加1,那当我们创建一个空的目录时,由于存在 . 与 .. 这两个目录,那么当我们创建一个空的目录/tmp/testing时,基本会有3个东西:
/tmp/testing
/tmp/testing/.
/tmp/testing/..
其中 /tmp/testing 和 /tmp/testing/. 都代表该目录,而 /tmp/testing/.. 则代表 /tmp 这个目录,所以当我们创建一个新目录,新的目录连接数为2,而上层目录的连接数则会增加1。
磁盘的分区、格式化、检验与挂载
如果要在系统中新增一块硬盘时,需要做以下动作:
- 对磁盘进行分区,以新建可用的分区
- 对该分区进行格式化,以创建系统可用的文件系统。
- 若想要仔细一点,则可对刚才新建好的文件系统进行检验。
- 在linux系统上,需要创建挂载点(也即是目录),并将它挂载上来。
磁盘分区:fdisk
$ fdisk [-l] 设备名称
参数:
-l: 输出后面接的设备所有的分区内容。若仅有fdisk -f时,则系统将会把整个系统能够找到的设备的分区均列出来。
# 例如:
# 先找出磁盘文件名
vagrant@vagrant-ubuntu-trusty-64:/tmp$ df /
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/hdc1 41251136 3631948 35883276 10% /
# 输入fdisk,但不要加上数字
vagrant@vagrant-ubuntu-trusty-64:/tmp$ fdisk /dev/hdc
它会提示Command(m for help): 输入m就可以看到相关参数提示
d 代表删除一个分区
n 代表新增一个分区
p 代表在屏幕中显示分区表
q 代表不存储,离开fdisk程序
w 代表将刚才的操作写入分区表
特别注意 q 和 w,只要离开fdisk时按下q,那么所有的操作都不会生效,相反按下 w 就是操作生效的意思。
删除磁盘分区
要删除分区(例如将/dev/hdc全部分区删除)需要做下面几步:
- fdisk /dev/hdc: 先进入fdisk界面
- p:先看下分区信息,假设要删掉/dev/hdc1
- d: 这个时候要选择一个分区,就选1
- w 或者 q: w可存储到磁盘数据表,并离开fdisk; 如果后悔,直接按下q就可以取消刚才的删除操作。
新增磁盘分区
需要进行一下的动作:
- fdisk /dev/hdc: 先进入fdisk界面
- n: 新增分区
- p 或 e 或 l:选择不同的分区类型,其中p代表主分区,e代表扩展分区,l代表逻辑分区
- 1 - 4:分区号,可选1-4,如果是逻辑分区,则不需要输入分区号
- 输入结束柱面号码,如果要自己计算柱面/分区的大小太麻烦,可以使用类似"+512M"的形式,来让系统帮我们分配最接近512M的柱面号码
- p: 查看分区信息
- w 或者 q: w可存储到磁盘数据表,并离开fdisk; 如果后悔,直接按下q就可以取消刚才的删除操作。
对于创建分区的形式(主分区/扩展分区/逻辑分区)以及分区的大小,一般来说新建分区的形式会有下面的几种情况:
- 1-4号尚有剩余,且系统未有扩展分区:此时会出现让你挑选Primary/Extended的选项,且你可以指定1~4号间的号码
- 1-4号尚有剩余,且系统有扩展分区:此时会出现让你挑选Primary/Logical的选项,若选择p你还需指定1~4号间的号码;若选择l则不需要设置号码,因为系统会自动指定逻辑分区的文件名号码
- 1-4没有剩余,且系统有扩展分区:此时不会让你挑选分区类型,直接会进入logical的分区形式
一般分区完是需要重启(reboot)才能更新内核的分区表信息,可以使用"partprobe"强制让内核重新找一次分区表
磁盘格式化
分区完毕后需要进行文件系统的格式化
$ mkfs [-t 文件系统格式] 设备文件
参数:
-t 可以接文件系统格式,例如ext3,ext2,vfat等(系统有支持才会生效)
# 例如将/dev/hdc6格式化为ext3文件系统
$ mkfs -t ext3 /dev/hdc6
如果是要指定文件系统的卷标,block的大小以及inode的数量,可以使用mke2fs
$ mke2fs [-b block大小] [-i block大小] [-L 卷标] [-cj] 设备
参数:
-b 可以设置每个block的大小,目前支持1024、2048、4096 byte三种
-i 多少容量给予一个inode
-c 检查磁盘错误,仅下达一次 -c 时,会进行快速读取测试,如果下达两次-c -c的话,会测试读写
-L 后面接卷标名称
-j 本来mke2fs是EXT2,加上-j后,会主动加入journal而成为EXT3
# 例如:文件系统的卷标设置为nancy_logical,block指定为2048大小,每8192 bytes分配一个inode,构建为journal的ext3文件系统,开始格式化/dev/hdc6
$ mke2fs -b 2048 -i 8192 -L "nancy_logical" -j /dev/hdc6
文件系统运行是会有硬盘与内存数据异步的状况发生,因此莫名其妙地司机非常可能导致文件系统的错乱,可以使用fsck来做磁盘检验
$ fsck [-t 文件系统] [-ACay] 设备名称
参数:
-t 如同mkfs一样,这是个综合软件,需要指定文件系统,linux会自动通过super block去分辨文件系统,通常不用指定这个参数
-A 依据/etc/sftab的内容,将需要的设备扫描一次,通常开机过程中会执行此命令
-a 自动修复检查到的有问题的扇区,所以不用一直按y
-y 与-a类似,但是某些文件系统仅支持-y这个参数
-C 可以再检验的过程中使用一个直方图来显示目前的进度
EXT2/EXT3的额外参数功能
-f 强制检查,一般来说如果fsck没有发现任何unclean的标志,不会主动进入细化检查的,如果你想要强制fsck进入细化检查,就得加入-f标志
-D 针对文件系统下的目录进行优化配置
# 例如强制检查 /dev/hdc6 这个设备
$ fsck -C -f -t ext3 /dev/hdc6
badblocks 用来检查硬盘或者软盘扇区有没有坏轨的命令
$ badblocks -[svw] 设备名称
参数:
-s 在屏幕上列出进度
-v 可以在屏幕上看到进度
-w 使用写入的方式来测试,建议不要使用此参数,尤其是待检查的设备已有文件
# 例如
$ badblocks -sv /dev/hdc6
磁盘的挂载与卸载
挂载点是目录,而这个目录是进入磁盘分区(实际上是文件系统)的入口,挂载之前需要确定:
- 单一文件系统不应该被重复挂载到不同的挂载点(目录)中
- 单一目录不应该重复挂载多个文件系统
- 作为挂载点的目录理论上应该是空目录
如果用来挂载的目录里面不是空的,那么挂载了文件系统的目录下的东西就会暂时消失。假设/home目录与根目录/在同一个文件系统,下面原本就有/home/test两个目录,如果想要添加新的硬盘,并且直接挂载在home下面,那么当挂载上新的分区时,则/home显示的是新分区内的数据,至于原先的test目录就会暂时被隐藏掉,并不是被覆盖掉,而是暂时隐藏起来,等到新分区被卸载,则/home原本的内容就会再次显示出来。
使用mount命令挂载文件系统
$ mount -a
$ mount [-l]
$ mount [-t 文件系统] [-l 卷标名] [-o 额外选项] [-n] 设备名称 挂载点
参数:
-a 依照配置文件/etc/fstab 的数据将所有未挂载的磁盘都挂载上去
-l 单纯输入mount会显示目前挂载的信息,加上-l可增列卷标(Lable)名称
-t 加上文件系统种类来指定欲挂载的类型,常见的linux支持类型有ext2、ext3、vfat、reiserfs、iso9660、nfs、cifs、smbfs(此三种为网络文件系统类型)
-n 在默认的情况下,系统会将实际挂载的情况实时写入/etc/mtab中,以利其他程序的运行,但在某些情况下(例如单用户维护模式)为了避免问题,会刻意不写入,此时就得要使用这个-n的参数了
-L 系统出了利用设备名称,还可以利用文件系统的卷标名称来进行挂载,最好为文件系统取一个独一无二的名称
-o 后面接一些挂载时额外加上的参数,比方说账号、密码、读写权限等:
ro, rw: 挂载文件系统成为只读ro或可读写rw
async, sync: 此文件系统是否使用同步写入(sync)或异步(async)的内存机制,默认为async
auto, noauto: 允许此分区被以mount -a自动挂载(auto)
dev, nodev: 是否允许此分区上可创建设备文件?dev为可允许
suid, nosuid: 是否允许此分区含有suid/sgid的文件格式
exec, noexec: 是否允许此分区上拥有可执行binary文件
user, nouser: 是否允许此分区让任何用户执行mount,一般来说,mount只允许root进行,但下达user参数,则可让一般user也能够对此分区进行mount
default: 默认值为rw、suid、dev、exec、auto、nouser、and async
remount: 重新挂载,在系统出错,或重新更新参数时有用,
# 例如挂载EXT2/EXT3文件系统
$ mkdir /mnt/hdc6
$ mkdir /dev/hdc6 /mnt/hdc6
$ df
$ unmount [-fn] 设备文件名或挂载点
参数:
-f 强制卸载,可用在类似网络文件系统(NFS)无法读取到的情况下
-n 不更新 /etc/mtab的情况下卸载
卸载后,可以使用 df 或者mount -l看看是否还存在目录树中
可以用dumpe2fs这个命令才查询卷标的名称
$ dumpe2fs -h /dev/hdc6
linux内核认识的设备文件是通过主设备代码(Major)和次设备代码(Minor)这两个数值来决定的,一般硬件文件名都已经被系统自动实时产生了,我们根本不需要手动创建设备文件,如果某些情况下需要创建,可以使用mknod命令
$ mknod 设备文件名 [bcp] [Major] [Minor]
参数:
设备种类:
b 设置设备名称成为一个外部存储设备文件,例如硬盘等
c 设置设备名称成为一个外部输入设备文件,例如鼠标/键盘等
p 设置设备名称成为一个FIFO文件
Major 主设备代码
Minor 次设备代码
如果要更改卷标(Label)的名称,可以使用e2label来更改设备的label名称
$ e2label 设备名称 新的Label名称
还要tune2fe的命令也可以修改设备相关参数
$ tune2fe [-jlL] 设备代号
参数:
-l 类似 dumpe2fs -h 功能,将super block内的数据读出来
-j 将ext2的文件系统转换为ext3的文件系统
-L 类似e2label的功能,可以修改文件系统的Label
设置开机挂载
如果要设置开机自动挂载我们想要的文件系统,可以再/etc/fstab里面修改,但系统挂载有一些限制:
- 根目录/是必须挂载的,而且一定要先于其他挂载点被挂载进来
- 其他挂载点必须为已新建的目录,可任意指定,但一定要遵守必须的系统目录架构原则
- 所有挂载点在同一时间之内,只能挂载一次
- 如若进行卸载,你必须先将工作目录移到挂载点(及其子目录)之外
# 查看 /etc/fstab这个文件内容
$ cat /etc/fstab
LABEL=cloudimg-rootfs / ext4 defaults 0 0
这个文件的内容有6个字段,分别代表:
第1列:磁盘设备文件名或该设备的Label
第2列:挂载点
第3列:磁盘分区的文件系统
第4列:文件系统参数,例如async/sync、auto/noauto、rw/ro、exec/noexec、user/nouser、suid/nosuid、usrquota、grpquota、defaults(同时具有rw,suid,dev,exec,auto,nouser,async等参数),基本上默认情况使用defaults设置即可
第5列:能被dump备份命令作用,0代表不要做dump备份命令,1代表每天进行dump操作
第6列:能否以fsck检验扇区,0代表不要检验,1代表最早检验(一般只有根目录会设置为1),2也是要检验
# 例如我们要将/dev/hdc6每次开机都自动挂载到/mnt/hdc6
# 首先先编辑/etc/fstab,写入下列信息
$ cat /etc/fstab
# 将下面信息写入
/dev/hdc6 /mnt/hdc6 ext3 defaults 1 2
# 用df查看是否被挂载了,如果是,需要先卸载
$ df
# 如果出现了/dev/hdc6的挂载信息,先卸载
$ unmount /dev/hdc6
# 最后测试下写入到/etc/fstab的语法有没有错误,这个很重要,因为这个写错了,linux可能无法顺利开机
$ mount -a
$ df
# 最后有看到/dev/hdc6被挂载起来的信息才是成功挂载,以后每次开机都会顺利将此文件系统挂载起来
/etc/fstab是开机时的配置文件,不过实际文件系统的挂载是记录到/etc/mtab与/proc/mounts这两个文件中。万一发生在/etc/fstab中输入的数据有误,导致无法顺利开机成功,可以进入单用户维护模式,重新挂载根目录
$ mount -n -o remount,rw /
如果下载了linux或者其他光盘DVD的镜像文件后,可以使用loop设备来挂载
# 假设要挂载/root/centos5.2_x86_64.iso这个镜像文件
$ ll -h /root/centos5.2_x86_64.iso
$ mkdir /mnt/centos_dvd
$ mount -o loop /root/centos5.2_x86_64.iso /mnt/centos_dvd
$ df
# 可以看下是否挂载成功
$ ll /mnt/centos_dvd
# 此时应该可以看到镜像文件的内容
内存交换空间swap的构建
在安装linux时一定需要的两个分区,一个是根目录,另外一个就是swap(内存交换空间)。swap的功能就是在应付物理内存不足的情况下所造成的内存扩展记录的功能。
创建swap的过程如下:
- 设置一个swap分区
- 分区:先使用fdisk在磁盘分出一个分区给系统作为swap。由于linux的fdisk默认会将分区的ID设置为linux的文件系统,所以可能还要设置一下system ID
- 格式化:利用新建的swap格式的 “mkswap 设备文件名” 就能够格式化该分区为swap格式。
- 使用:最后将该swap设备启动,方法为“swapon 设备文件名”
- 查看:最终通过free这个命令来查看一下内存的使用情况
- 创建一个虚拟的内存文件
$ fdisk /dev/hdc
Command (m for help): n
: +256M
Command (m for help): P
Command (m for help): t //修改系统ID
Partition number(1-7): 7 //七号分区
Hex code(type L to list codes): 82 //改为swap的ID
Command (m for help): P
Command (m for help): w
# 此时分区表更新
# 强制更新内核分区表
$ partprobe
# 开始构建swap格式
$ mkswap /dev/hdc7
# 开始查看与加载
$ free
# 将swap设备启动
$ swapon /dev/hdc7
# 再进行查看
$ free
由于现在桌面计算机内存已经足够大,swap一般不需要用到,但如果是服务器,swap还是需要的。如果主机支持电源管理模式,也就是当linux主机进入休眠模式,那么允许当中的程序状态则会被记录到swap去,以做唤醒主机的状态依据,另外在某些程序运行时,本来就会利用swap的特性来存放一些数据段,所以swap还是需要创建的,不过他有一定的限制:
- 在内核2.4.10版本以后,单一swap已经没有2GB的限制了
- 最多仅能创建32个swap
- 由于目前x86_64(64位)最大内存寻址到64GB,因此swap总量最大也是仅能达64GB
fdisk分区无法支持到2TB以上的分区,此时需要用parted来处理。
$ parted [设备] [命令[参数]]
参数:
命令功能
新增分区: mkpart [primary|logical|extended] [ext3|vfat] 开始 结束
分区表:print
删除分区: rm [partition]
#例如列出本区的分区表资料
$ parted /dev/hdc print
分区表一般分为6个部分:
Number: 分区号码
Start: 起始的柱面位置,它以容量作为单位
End: 结束的柱面位置
Size: 由上述两者的分析,得到这个分区有多少容量
Type: 就是分区的类型,有primary、extended、logical等类型
File system:文件系统类型
# 例如创建一个新的分区,分区的起始可以根据上面显示的分区列表找到最后一个柱面位置来作为新分区的其实位置
$ parted /dev/hdc mkpart logical ext3 19.3GB 19.7GB
# 删掉刚才新建的8号磁盘分区
$ parted /dev/hdc rm 8
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。