[RHEL]-13-inode与软硬连接

引言

inode就像是硬盘中数据的索引,保存着数据的元信息,通过这些元信息,系统能够很快的检索到数据块存放的位置,从而读取数据。

文章目录

0×1.inode是什么

inode就是硬盘数据的索引信息,每个inode存放的内容如下:

● 文件的字节数;
● 文件拥有者的User ID;
● 文件的Group ID;
● 文件的读、写、执行权限;
● 文件的时间戳,共有三个:ctime指inode上一次变动的时间,mtime指文件内容上一次变动的时间,atime指文件上一次打开的时间;
● 链接数,即有多少文件名指向这个inode;
● 文件数据block的位置

可以使用stat查看某个文件的inode信息:

					#除文件名外的所有属性大部分都储存在inode中,因为系统并不会像人一样使用文件名去索引文件数据,而是使用inode去索引文件数据的地址
					[qing@qingsword.com ~]$ stat /etc/passwd
					  文件:'/etc/passwd'
					  大小:2424      	块:8          IO 块:4096   普通文件
					设备:801h/2049d	Inode:267545      硬链接:1
					权限:(0644/-rw-r--r--)  Uid:(    0/    root)   Gid:(    0/    root)
					最近访问:2016-08-26 17:58:02.562508562 +0800
					最近更改:2016-08-26 17:58:02.562508562 +0800
					最近改动:2016-08-26 17:58:02.562508562 +0800
					创建时间:-
					

既然inode本身保存了索引数据,那么其自身也是会占用磁盘空间的,不知道大家注意没有,在我们给磁盘分区时,分区的实际大小会小于我们指定的大小,这就是因为,系统自动的计算出了对应分区大小所需要的inode数,在其中扣除了存放inode信息所需要的空间;

假设我们一个分区是20G,一般inode块占用128或256字节,在ext4文件系统中默认inode占用256字节,这个分区理论可以创建的inode数量为(20*1024*1024*1024/256=83886080),但分区还需要储存其他的文件数据,实际上创建的inode数量要远小于这个数量,这取决于每个文件系统不同的算法优化,这里不做深究,可以使用df -i命令来查看每个分区可以创建的inode总量,和已经使用的百分比:

					[qing@qingsword.com ~]$ df -i
					Filesystem                        Inodes  IUsed    IFree IUse% Mounted on
					/dev/sdb2                       15727616     13 15727603    1% /mnt/sdb2
					/dev/mapper/rhel_qingsword-home 26415104     16 26415088    1% /home
					/dev/sda1                         409600    328   409272    1% /boot
					

因为每个文件都需要一个唯一的Inode,而一个很大的文件可能会占用很多数据块(block),这个文件的inode只需要指向第一个数据块,然后每个数据块的块尾都会指向下一个数据块地址,形成一个块链,所以一个分区上的文件越小,越消耗inode数量,假设有一个恶意程序,不断的创建空的文件,以至于耗光分区所有的inode,我们就会发现,磁盘空间还有剩余,但却不能创建新的文件了,可以使用ls -i来查看每个文件的inode号是多少:

					[qing@qingsword.com ~]$ ls -i
					2392071 1              2366246 infile.txt
					2370209 if.py          2362609 logical     2366579 stdin.txt
					2366617 ifshell.sh     2368532 nothion     2370495 version.sh
					

表面看来,用户是通过文件名称来查看文件,但系统内部查看文件时,首先要找到文件对应的inode值,然后通过inode值,获取inode信息,再根据inode信息,找到文件数据所在的block,读出数据。

有时候一些恶意软件创建了一些带有特殊字符的文件,我们无法通过文件名去删除这些文件,这个时候就能够通过查找inode号来删除对应的文件,下面是一个简单实例:

					#假设当前目录下的1为一个特殊字符文件名的文件,首先查看到它的inode号为2392071
					[qing@qingsword.com ~]$ ls -i
					2392071 1              2366246 infile.txt

					#方法一:通过find命令搜索当前目录下的inode号,再交由rm命令删除
					[qing@qingsword.com ~]$ find . -inum 2392071 -exec rm -rf {} \;

					#方法二:直接使用find命令自带的delete参数
					[qing@qingsword.com ~]$ find . -inum 2392071 -delete
					

实际上Linux系统中的目录只是"目录文件",目录文件中保存着:文件名和对应文件名的inode号;这就是inode信息中不需要包含文件名的原因,两者的信息是分开储存在"目录文件"中的。

0×2.Linux系统中的软连接与硬链接

在了解了上面这些inode知识后,再来看硬链接软连接是如何工作就会变得十分容易理解,我们知道每个文件名都对应了一个inode,每个inode都指向了一个block数据块,用于访问文件数据,而硬连接只是在文件目录中新建一个文件名,和另一个文件指向同一个inode,请看下面的实例:

					#touch一个文件file_a
					[qing@qingsword.com ~]$ touch file_a
					
					#查看这个文件的inode号(2491080),以及连接数(1)
					[qing@qingsword.com ~]$ ls -li
					2491080 -rw-rw-r-- 1 qing qing 0 11月 20 21:49 file_a

					#现在给这个文件创建一个硬链接file_b,语法:ln [原文件名] [新连接文件名]
					[qing@qingsword.com ~]$ ln file_a file_b

					#两者的inode相同,连接数也变成了2
					[qing@qingsword.com ~]$ ls -li
					2491080 -rw-rw-r-- 2 qing qing 0 11月 20 21:49 file_a
					2491080 -rw-rw-r-- 2 qing qing 0 11月 20 21:49 file_b

					#修改其中一个文件的内容,两者的内容都会变化(因为两个文件名对应的是同一个inode,而同一个inode指向的是同一个数据块地址)
					[qing@qingsword.com ~]$ echo www.qingsword.com > file_a
					[qing@qingsword.com ~]$ cat file_a file_b
					www.qingsword.com
					www.qingsword.com
					
					#只要有一个硬连接文件存在,就能够访问这个inode指向的数据,删除file_a,file_b照样访问inode所指向的数据
					[qing@qingsword.com ~]$ rm -rf file_a
					[qing@qingsword.com ~]$ cat file_b 
					www.qingsword.com
					

对于一个目录,硬链接数量永远是2加上它的子目录数(包含隐藏目录),原理其实很简单,目录创建时,会在目录中生成两个特殊结构的目录"."和"..",其中"."代表目录本身,实际上就是当前目录的一个硬链接,此时这个目录的硬链接数量就变成了2,而".."指向了父目录,相当于父目录的硬链接,所以在这个目录中的所有子目录,都有一个硬连接".."指向当前目录,所以"一个目录,硬链接数量永远是2加上它的子目录数",验证如下:

					#创建一个目录
					[qing@qingsword.com ~]$ mkdir dir_a
					
					#查看目录的硬链接数量,发现空目录的硬链接数量已经是2,上面已经做了解释
					[qing@qingsword.com ~]$ ls -dl dir_a/
					drwxrwxr-x 2 qing qing 4096 11月 20 21:58 dir_a/

					#进入目录,创建一个子目录
					[qing@qingsword.com ~]$ cd dir_a/
					qing@qingsword:~/test/qings/dir_a$ mkdir sub_a

					#发现当前目录"."的硬链接数量变成了3,即2加上子目录数
					qing@qingsword:~/test/qings/dir_a$ ls -al
					drwxrwxr-x 3 qing qing 4096 11月 20 21:59 .
					drwxrwxr-x 3 qing qing 4096 11月 20 21:58 ..
					drwxrwxr-x 2 qing qing 4096 11月 20 21:59 sub_a

					#再创建一个目录,此时当前目录"."硬链接数量变成了4
					qing@qingsword:~/test/qings/dir_a$ mkdir sub_b
					qing@qingsword:~/test/qings/dir_a$ ls -al
					drwxrwxr-x 4 qing qing 4096 11月 20 22:00 .
					drwxrwxr-x 3 qing qing 4096 11月 20 21:58 ..
					drwxrwxr-x 2 qing qing 4096 11月 20 21:59 sub_a
					drwxrwxr-x 2 qing qing 4096 11月 20 22:00 sub_b
					

除了硬链接,还有一种特殊的连接,即软连接,软连接不会创建一个指向inode的文件名,而是创建一个指向文件名的新文件名,新的文件和被指向的文件拥有不同的inode号,因为指向的是文件名而非inode,所以当被指向的文件删除后,新文件将会无法访问,请看下面的实例:

					#软连接创建语法:ln -s [被指向的文件名] [新文件名称]
					#软连接创建后,文件的连接数不会发生变化
					[qing@qingsword.com ~]$ ln -s file_b file_a
					[qing@qingsword.com ~]$ ls -li
					2514972 drwxrwxr-x 4 qing qing 4096 11月 20 22:00 dir_a
					2495764 lrwxrwxrwx 1 qing qing    6 11月 20 22:05 file_a -> file_b
					2491080 -rw-rw-r-- 1 qing qing   18 11月 20 21:50 file_b

					#被指向的文件存在时,软连接文件访问正常,但当被指向文件删除时,软连接文件就无法访问数据了
					[qing@qingsword.com ~]$ cat file_a
					www.qingsword.com
					[qing@qingsword.com ~]$ rm -rf file_b
					[qing@qingsword.com ~]$ cat file_a
					cat: file_a: 没有那个文件或目录