文件系统入门
Windows和DOS常用的文件系统是fat系列,Linux主要使用的文件系统是ext3。在UNIX/Linux系统中,除根目录外,所有文件和目录都包含在相应的目录文件中,目录是UNIX/Linux文件系统的一个基本特征。
1.文件系统的结构
1.1目录结构和文件名
UNIX/Linux系统的目录结构以层次形式组织,称为层次结构或树状结构。根目录是所有目录的起始点,所有其他目录都直接或间接地从它分支而来,每个目录包含文件和子目录,形成在广度和深度上延伸的一颗目录树,如下图:
图1.1 树状目录结构
其中“/”是根目录,也是bin、dev等子目录的父目录,而bin、dev则称为根目录的子目录。事实上,目录是子目录和文件的一个列表,是一种结构化的文件,每个子目录或文件占用一个目录项。UNIX/Linux系统中的目录项通常如图4.2所示:
文件名 | 索引节点编号 |
· | 45254 |
·· | 23 |
子目录名1 | 64645 |
子目录名2 | 824207 |
文件名1 | 67621 |
文件名2 | 73486 |
··· | ··· |
图1.2 目录形式
其中“.”表示当前目录,“..”表示父目录,除根目录之外的所有目录都自动包含这两个目录项。每个目录项都由文件名和索引节点编号(即i节点)组成。UNIX/Linux的文件系统有一个存储i节点表的空间,文件系统中的每一个文件在该表中部分配有一个i节点,所有的i节点都有相同的大小,每个i节点都通过在表中的位置来标识,用来存储文件的属性信息,如文件大小、文件权限、最近修改时间和指向文件所占用的数据块等。
文件是UNIX/Linux操作系统处理信息的基本单位。UNIX/Linux的文件系统有普通文件、目录文件、设备文件、符号链接文件等。每个文件都包括文件本身内容和属性信息(在i节点中)两部分。文件在文件系统中通过文件名来进行存取等操作。
1.2 文件系统结构(转载)
磁盘是由若干扇区组成,每个扇区有512B(将磁盘存储区扇区化是为了更好的管理磁盘)。又由若干个扇区组成一个块(ext2默认是由8个扇区组成一个块,即4kb,这里为了简化说明,就把2个扇区组成一个块,即1kb)。由图知,将磁盘分成若干个分区,每个分区由若干个块组成。
- 自举块(boot block):占用1 block;主要存储分区的操作系统类型、分区起始地址;pc联盟规定的大小,和各个文件系统无关;每个分区只有一个;
- 超级块:占用1 block;存储分区操作系统版本、块大小、文件系统;
- 块组描述表(GDT):占用3 block;存储一个块组的描述信息;
- 块位图(block bitmap):占用1 block;每个比特位表示一个数据块是否被标记使用;1:已使用,0:未使用;
- inode 位图(inode bitmap):占用1 block;每一个比特位表示一个inode节点。1:已使用,0:未使用;
- inode节点:占用128B;分为文件属性部分和数据指针部分;数据指针占用60B,长度为15的指针数组;每个数据块的大小是1 block,那么15个指针最多只能维护15*1K个文件大小,显然,文件大小的上限太小了。所以文件系统通过三级间接寻址的方式来提高文件大小的上限。块大小若以1 block计算,文件大小的上限为16G,若以4 block为块大小,那文件大小的上限超过了1T;ext4文件系统中,数据指针有256B,那文件大小上限就非常大了;
- 数据块:存储文件的内容;
三级间接寻址策略
三级间接寻址图
将数据指针数组命名为data数组。文件系统中,将data[12]进行一级间接寻址。即:将data[12] 指针指向的数据块,转化为一个更大的指针数组,长度为1024/4=256。在将这个更大的指针数组的分别数指向256个数据块;data[13]进行二级间接寻址,data[14] 进行三级间接寻址。都和一级间接寻址同理。
目录文件
数据块存储内容
数据块中存储的是一条一条的记录项,每条记录项都由文件名、indoe编号、记录长度(该记录项首地址到下一条记录项的首地址的长度)。每一个记录项就是该目录下“ls -a”的结果。
普通文件结构
由图可以看出,每个inode节点可以对应多个数据块,和上文在分析inode节点的内容一致。然后,若干个目录块中的记录项指向每个inode节点,通过inode节点中链接数这个数据成员来标识指向其的记录项个数,这就是硬链接。当然,这些目录块都是目录文件的数据块;
目录文件结构
由上图知,inode节点在文件系统中被维护成了结构体数组,inode编号为数组的下标;2549号i节点是1267号i节点的子目录,因为1267号i节点的数据块中有2549号i节点的记录项;“.”目录文件和 “..”目录文件都是硬链接。
从以上分析能够得出结论:所有的目录块都是不同目录文件的数据块。
文件创建和查询过程
执行命令:mkdir /home/aaron/a.c
(1)通过块位图区找到空闲的数据块,存放a.c中的内容
(2)通过inode位图区找到空闲的inode节点块,生成相应的inode节点
(3)在aaron目录文件的数据块中添加一条a.c的记录项
执行命令:vim /home/aaron/a.c
(1)找到inode编号为2的inode节点,
(2)遍历根目录文件的数据块中的记录项,匹配aaron记录项,获取其inode编号
(3)通过aaron目录文件的inode编号,找到aaron文件对应的数据块
(4)遍历aaron文件的数据块中的记录项,匹配a.c记录项。同理,找到对应的a.c的数据块。用vim打开相应文件
- unix和Linux系统是通过文件名来对应inode节点号,从而找到对应的数据块,完成文件查询的过程
- inode节点中没有文件名就是因为基于这种定位文件位置的机制
1.3绝对路径和相对路径
文件系统中的路径用来定位文件,从根到文件所处位置所经过的目录的序列就构成了路径。UNIX/Linux文件系统中可以使用绝对路径和相对路径两种形式来访问文件。绝对路径就是从根目录出发到该文件的路径。因此绝对路径总是以“/”(代表根目录)开始,例如图1.1中文件wife的绝对路径就是/home/zhangsan/wife。绝对路径精确地指明了文件所处的位置,所以不管当前在哪个目录下工作,都可以用此来指定任何目录中的文件位置。相对路径是从当前工作目录开始到文件所处位置的路径。假设当前正在图1.1的home目录下工作,则访问wife的相对路径就是zhangsan/wife,访问bin目录的相对路径是../bin。在相对路径中经常使用"."来代表当前路径,使用".."来代表父路径。
2.文件系统的使用
下面介绍Linux中提供的用来操作文件和目录的一些命令。
2.1查看当前工作目录
pwd命令用来显示当前工作目录的绝对路径,该命令不带任何选项和参数,如:
[shawnee@localhost ~]$ pwd
/home/shawnee
2.2改变当前目录
改变当前工作目录的命令是cd,可以让用户从一个目录转到另一个目录下去工作:
[shawnee@localhost ~]$ cd /home
[shawnee@localhost home]$
另外,不带任何参数的cd命令可以让用户从系统的任何目录中回到用户主目录:
[shawnee@localhost test]$ cd
[shawnee@localhost ~]$
2.3查看目录内容
ls命令用来查看指定目录的内容,如果参数是目录则列出目录下的子目录和文件信息,如果参数是文件则列出该文件名及相关信息,如果没有指定目录或文件,则列出当前目录下的子目录和文件信息。缺省输出信息按文件名的字母顺序排列。
使用格式为: ls [-选项] [目录或文件]
常用的选项有:
-a:显示指定目录中所有的文件,包含以“.”开头的隐藏文件
-c:按文件的修改时间排序显示
-i:显示每个文件的i节点号
-l:以长格式显示文件的详细信息
-s:以块为单位显示每个文件的大小
-S:按文件从大到小顺序显示
-R:循环列出子目录的内容
[shawnee@localhost ~]$ ls -l
总用量 4
drwxrwxr-x. 2 shawnee shawnee 21 1月 30 05:28 test
-rw-rw-r--. 1 shawnee shawnee 439 1月 30 02:31 whoput
drwxr-xr-x. 2 shawnee shawnee 6 1月 25 09:05 公共
drwxr-xr-x. 2 shawnee shawnee 6 1月 25 09:05 模板
drwxr-xr-x. 2 shawnee shawnee 6 1月 25 09:05 视频
drwxr-xr-x. 2 shawnee shawnee 6 1月 25 09:05 图片
drwxr-xr-x. 2 shawnee shawnee 6 1月 25 09:05 文档
drwxr-xr-x. 2 shawnee shawnee 6 1月 25 09:05 下载
drwxr-xr-x. 2 shawnee shawnee 6 1月 25 09:05 音乐
drwxr-xr-x. 2 shawnee shawnee 6 1月 25 09:05 桌面
总用量列出占用的数据块的多少。输出的信息有7列,依次为文件类别和权限、链接数、文件拥有者、文件所属组、文件大小、文件创建或修改时间、文件名。
表示文件类别和权限的第一列有10个字符,第一个字符表示文件类型,代表的含义如下:
-:普通文件
d:目录文件
b:块设备文件
c:字符设备文件
l:符号链接文件
第一列的后面9个字符代表3组访问权限,分别授予:所有者、同组用户、其他用户。每一组的3个字符分别代表读、写、执行权限,-表示没有相应权限。
2.4查看文件类型
file命令用来显示指定文件的类型(可以用多个文件名作为参数):
[shawnee@localhost ~]$ file test whoput
test: directory
whoput: UTF-8 Unicode text
2.5更改文件权限和存取时间
(1)更改文件权限命令 chmod
该命令用来改变指定文件或目录的访问权限。其使用格式为:
chmod mode 文件名或目录名:
#chmod 764 whoput
该命令将使文件whoput的权限更改为111110100,即文件所有者有读、写、执行权限,同组用户有读、写权限,其他用户只有读权限。
chmod也可以使用符号来改变权限mode:(user,group,other,all)
#chmod u=r+w+x,g=r+w,o=r whoput
例:给test的所有用户增加执行权限:
#chmod a+x test
chmod还有另外一个可用的选项-R用来更改指定目录中所有文件和子目录的权限,如:
#chmod -R a+r /home/sharefolder将使sharefolder文件夹的所有内容供所有用户读取。
(2)更改文件存取时间命令 touch
该命令用来更改指定文件的存取和修改时间,缺省更改为系统当前时间。如果指定文件不存在,则创建一个新的空文件:
-a:只更改存取时间
-m:只更改修改时间
-d time:使用指定的时间来修改,time格式为yyyymmddhhmm.ss。
#touch test 将文件test的存取和修改更改为当前时间
#touch -d 20100718 touchfile 创建touchfile,并将存取和修改时间设为2010年7月18日
2.6查看文件内容
(1)cat命令
该命令可以依次显示一个或多个文件,也可以用来连接文件。
例:显示当前目录中文件whoput的内容:
#cat whoput
例:将当前目录中文件txtfile1、txtfile2连接成一个文件txtfile:
#cat txtfile1 txtfile2>txtfile
(2)more命令
该命令用来分页显示指定文件的内容,每显示一页(屏)后暂停,并在底部高亮度显示已显示内容所占文件百分比,如--More--(8%)。此时,按空格键显示下一页内容,按Enter键向下翻一行,按q键退出命令。
例:分页显示当前目录下文件txtfile的内容:
#more txtfile
(3)less命令
该命令是Linux系统中比more更高级的显示文件内容命令,允许在文件中向后或向前浏览。其用法类似于more.
(4)head命令
该命令用于显示指定文件的前几行。可以用来快速确认是不是所需的文件:
#head txtfile
缺省显示文件的前10行。也可以使用选项来指定:
-nums:显示文件的前nums行。
-c nums:显示文件的前nums个字符。
(5)tail命令
该命令用来显示文件的最后几行:
#tail txtfile
缺省显示文件的最后10行。也可以使用选项来指定:
-nums:显示文件的最后nums行。
-c nums:显示文件的最后nums个字符。
2.7创建和删除目录
(1)创建目录命令mkdir
该命令能够在指定的路径下创建一个新的子目录,如:
#mkdir /home/student/music
-m权限:为新建目录设置权限,权限使用3个八进制数字表示
-p:一次创建多个目录
例:在点钱目录下建立一个名为newdir的新目录,同时在该新创建的目录下再创建一个childdir目录。
#mkdir -p newdir/childdir
(2)删除目录命令rndir
该命令用于删除指定路径下的一个或多个空目录,如:
#rmdir /home/student/music
将删除上面所建立的music目录,前提是music目录下已经没有内容。
常用的选项是-p,该选项在删除目录后,如果其父目录也为空,将一同删除。
2.8复制、移动、删除、链接
(1)复制文件命令cp
例:将当前目录下的whoput文件复制到/home/student目录下
#cp whoput /home/student
例:将目录/usr/mary 下的所有子目录和文件复制到目录/home/liuliu中
#cp -r /usr/mary /home/liuliu
(2)移动命令mv
若在不同路径下,将进行移动操作,相当于搬家;若在相同路径下,将进行更名操作
例:将当前目录下的test文件移动到/home/student目录下
#mv test /home/student
例:将当前目录下的function.txt文件更名为myfun.c文件
#mv function.txt myfun.c
(3)删除命令rm
例:递归地(-r)删除目录/usr/mary/music下的所有文件及其子目录
#rm -r /usr/msry/music
使用rm命令要小心,一旦文件被删除,是不能恢复的
(4)建立链接命令ln
该命令能够为指定的文件在另一个位置建立一个链接。当需要在不同的目录下用到相同文件时,不需要再每一个目录下都放一个相同的文件,而只要在一个位置存放该文件,然后在其他用到该文件的地方用ln命令建立链接(link)即可,这样就避免了重复占用磁盘空间。而且只要在一个地方对文件进行了修改,在任何地方引用该文件,都会看到对文件所做的改动。
ln命令在不使用任何选项时建立的链接为硬链接,如:
#ln test /home/student/mytest
此时,mytest和test不分主次,只是一个文件的不同名字而已,都指向该文件在磁盘上的存放位置。事实上建立硬链接只是在链接所在的目录文件中增加一个目录项,而目录项中的i节点号和源文件所在目录项中的i节点号相同,即对同一个文件i节点号的多次引用。
硬链接有如下限制:不能对目录建立硬链接,不能在不同的文件系统间建立硬链接。
而符号链接则没有这些限制。建立符号链接需要使用-s选项,如:
#ln -s /user/mary/test /home/student/mylink
与硬链接不同的是,符号链接确实建立了一个新文件,所以mylink是一个新的文件,只是在对该文件进行读写时,和访问/usr/mary/test文件一样,有点类似于Windows下的快捷方式。事实上,符号链接文件的内容存放的是被链接文件的路径
2.9统计、排序、比较
(1)统计文件内容命令wc
该命令用来统计指定文件的行数、字数和字符数,常用选项为:
-c:统计字符数
-l:统计行数
-w:统计字数
例:统计当前目录下test文件行数、字数和字符数:
#wc test
则依次输出文件test的行数、字数和字符数。
(2)排序命令sort
该命令用来对指定文件中所有的行进行排序,并将结果显示在标准输出上。若不指定输入文件,则排序内容将来自标准输入。
排序是根据从输入行抽取的一个或多个关键字进行比较来完成的。排序关键字定义了用来排序的最小的字符序列。缺省情况下以整行为关键字按ASCII字符顺序进行排序。
-o filename:将排序输出写到输出文件中而不是标准输出。
例:将当前目录下的test文件进行排序,并将排序结果输出到文件sorttest中。
#sort -o sorttest test
(3)比较文件内容命令comm和diff
comm命令用来对两个已经排好序的文件进行比较,comm读取这两个文件,其格式为:
comm [-123] file1 file2
然后生成三列输出:仅在file1中出现的行;仅在file2中出现的行;在两个文件中都存在的行。如果文件名用“-”则表示从标准输入读取。选项1、2、3表示不显示相应的列,如:
#comm -12 file1 file2 则只输出file1和file2中共有的行。
diff命令用来逐行比较两个文本文件,列出其不同之处。它不要求事先对文件进行排序。
2.10查找文件
find命令用来在目录结构中查找文件所在的位置,并执行相应的操作。其使用格式为:
find 搜索路径 搜索选项 执行动作
搜索路径指明从哪里开始查找,find会递归地搜索其包含的所有子目录;搜索选项指明查找内容;执行动作指明一旦找到所要的文件如何处理。
例:在/usr/mary 中查找所有的.c源文件,并把查找结果输出到屏幕上
#find /usr/mary *.c -print
例:在根目录下查找并删除tmpfile文件,但在删除前要求确认。
#find / -name tmpfile -ok rm {} \;
2.11文件内容检索
grep命令用来在指定文件中检索匹配指定字符串的行,其使用格式为:
grep [选项] 要检索的字符串 文件名
常用的选项有:
-c:只输出匹配行的计数总数
-i:匹配时不区分大小写
-n:显示匹配行及行号
-v:显示不包含匹配文本的所有行
例:在/etc/passwd中查找包含mary的所有行:
#grep mary /etc/passwd
整理自《UNIX/Linux应用基础教程》
参考博客:http://www.linuxidc.com/Linux/2017-09/146740.htm(Linux文件系统结构)