今天将重点介绍Linux中硬链接和软连接,其中会涉及到索引节点(inode),以及cp命令,rm命令,mv命令在执行的过程中对inode的影响。

inode 索引节点

  • inode(index node)表中包含文件系统中所有文件列表。 这里所说的文件系统指的是一个分区内部的文件系统。不同分区之间的inode节点号是可以重复。

  • 一个节点(索引节点)是在一个表项,包含有关文件的信息,包括
    文件类型,权限,UID,GID
    连接数,指向这个文件名的连接的次数
    该文件的大小和不同的时间戳
    指向磁盘上文件的数据块的指针
    有关文件的其他数据

  • 通俗的来说可以这样来理解,每个中国(一个Linux分区,Linux系统可看作全球)公民(分区中的文件)都有一个唯一的×××号(inode),而每个人可以有多个名字(文件名),名字是可以重复的。也就是说,不同的省份(类似与同一个分区下不同的目录内)可以有叫同样名字的人,但是每个名字(文件名)所指向的实体(文件数据)也是不同的。同一个实体的名字会有多个,去掉其中一个对该实体并不会有影响。同样如果一个人,没有名字,他也是客观存在的。在Linux系统中也是同样的道理。我们会在文末结合rm命令,cp命令,mv命令来阐述这个原理。


数据存储简易图示


其实了结计算机组成原理的人都会明白,计算机存储是地址和数据分开存储的。系统在读取文件的过程中,首先是通过系统中记录的文件地址找到该文件的数据块所在的位置,然后读取出该数据的相关信息。

只不过在Linux 文件系统的节点表中,不仅仅存储了该文件的节点信息,同时还存储了该文件的元数据,也就是属性信息,这些信息中包含了文件的大小,Access time ,Modify time,Change time,等,同时还有文件的创建者,所有者,文件的类型等等。这些数据都属于文件的元数据。

文件存储的详细图示

 
假设数据块的大小为4K,每个指针都指向一个数据块。假设有10个直接指针,4个间接块指针,2个双重简介块指针,一个3重间接指针。

  • 假设一个数据小于4K,一个数据块就足够了,此时,只需要一个直接指针指向一个数据块就足够了。

  • 假设一个数据块为10K,一个数据块不足够使用,那么就使用3个直接指针指向的数据块就足够。

  • 间接指针会指向 一个数据块,这个数据块不是用来存储数据的,而是用来存储指针的,每个指针的大小为4K,那么这个数据块可以存储的指针个数为1024个,那么这个简洁指针可以存储的数据块的个数就是1024块

  • 同理,双重间接指针指向的第一个数据块也是能够存储1024个指针,同时每个指针指向的数据块也是用来存储地址的,此时一个双重间接指针可以存储的数据块的个数为1024×1024块

这样这个文件系统能够存储的单个文件的最数据的大小为 10×4K+4×1024×4K+2×1024×1024×4K+1×1024×1024×1024×4K

而由于指针的存在所占用的存储空间会根据文件系统的不同而有所不同。

inode表的示意图

  • 文件引用一个是inode 号

  • 人是通过文件名来引用一个文件

  • 一个目录是目录下的文件名和文件inode号之间的映射

  • 如果一个文件创建了硬链接,inode号是一样的,并且他们指向的是同一段文件数据。

cp命令和inode

执行cp命令之后,会在系统中分配一个空闲的inode 号,在inode表中生成新的条目,在目录中创建一个目录项,将名称与inode号关联,拷贝数据生成新的文件。

	// 执行cp 命令复制一个文件file1 到file1cp
	cp file1 file1cp  
	  
	//ls命令的 -i 选项可以查看inode 节点号
	ls -il
	
	//67 和 68 显示的就是inode节点号
	
	67 -rw-r--r--. 1 root root 0 Jul 19 21:33 file1
	68 -rw-r--r--. 1 root root 0 Jul 19 21:36 file1cp

rm命令和inode

执行rm 命令之后, 实际上删除的是该文件的指针,以及目录项。

  • 链接数递减,从而释放的inode号可以被重用

  • 把数据块放在空闲列表中

  • 删除目录项

  • 数据实际上不会马上被删除,但当另一个文件使用数据块 时将被覆盖。

	//使用ln 命令可以给file1创建一个硬链接文件  
	ln file1 file1ln 

	ls -li
	
	//可以看出硬链接文件file1ln 与 file1 具有相同的元数据以及inode号
	//他们的链接数为2,可以理解为有两个指针指向了该文件数据。
	67 -rw-r--r--. 2 root root 0 Jul 19 21:33 file1
	68 -rw-r--r--. 1 root root 0 Jul 19 21:36 file1cp
	67 -rw-r--r--. 2 root root 0 Jul 19 21:33 file1ln  

	//根据上面展示的消息我们执行 rm 命令
	rm -rf file1
	
	//结果显示file1ln的文件链接数减为1 但是 file1ln 查看的内容和file1是一致的。
	68 -rw-r--r--. 1 root root 0 Jul 19 21:36 file1cp
	67 -rw-r--r--. 1 root root 0 Jul 19 21:33 file1ln

如果此时我们再执行一遍 rm -rf file1ln 文件系统中将不会再有指针指向 之前file1 和file1ln 所对应的数据块。但是该数据块不会立马被删除掉,如果将来有其他数据需要使用该数据块时,它将被删除掉。

mv命令和inode

  • 如果mv命令的目标和源在相同的文件系统,作为mv 命令
    用新的文件名创建对应新的目录项
    删除旧目录条目对应的旧的文件名
    不影响inode表(除时间戳)或磁盘上的数据位置:没有 数据被移动!

  • 如果目标和源在一个不同的文件系统, mv相当于cp和rm

ln 硬链接

硬链接 针对一段文本块创建了两个名字。
可以通俗的理解为 给一个房间开了两扇一摸一样的门,两扇门是平等的,关闭任何一扇门都不会对从另一扇门进入房间产生影响。
链接创建之后与源文件路径是平等的关系。
硬链接不能针对文件目录进行创建,因为硬链接指向的是文件数据本身。

我们在实验目录中创建一个文件f1,同时为其创建一个硬链接。

	ln f1 f1ln 
	
	//执行此命令 并观察相关元数据  
	ll -i  
	
	67 -rw-r--r--. 2 root root 12 Jul 20 08:45 f1 
	67 -rw-r--r--. 2 root root 12 Jul 20 08:45 f1ln

从结果中可以看出,两个文件除了文件名不一样以外,其他的全部都一样,就连a,m,c,时间都一样的复制过来。这时如果来查看两个文本文件的话,会发现他们是一样的。同理,我们修改了f1文件,f1ln文件也会发生相应的变化。

	//我们使用touch 命令来刷新文件f1的时间 
	touch f1   

	//执行此命令观察元数据  
	67 -rw-r--r--. 2 root root 12 Jul 20 08:50 f1
	67 -rw-r--r--. 2 root root 12 Jul 20 08:50 f1ln

可以看出两个文件的时间都发生变化。当然,如果修改了f1文件的内容结果还是一样。

	//追加文本  
	echo "HelloTest" >> f1ln  

	ll -i  
	
	//文件的大小发生了变化
	67 -rw-r--r--. 2 root root 22 Jul 20 08:54 f1
	67 -rw-r--r--. 2 root root 22 Jul 20 08:54 f1ln

下面我们画一个示意图来理解一下

现在我们来执行下面的命令

	//我们删除掉文件f1
	rm -rf f1

根据图示我们可以看出虽然删除了f1(实际上删除的是文件数据块上的名字叫做f1的地址),但是我们仍然能够使用f1ln 文件来访问到该文件数据块。
这就是硬链接的特点。
从另一个角度上说,如果我们把f1 和 f1ln都删除掉之后,表面上我们是删除掉了该文件,但实际上我们只是删除掉了该文件数据块的两个硬链接,该文件数据块实际上还存储在硬盘上,直到有新的数据文件占用该存储空间后,原来的数据才会被擦除掉。
也正是因为这个原因,我们删除掉的数据,在有限的时间范围内还是有可能被恢复回来的。

ln -s 软链接

Linux 系统中的软连接可以理解为win 系统中的快捷方式。

  • 一个符号链接指向另一个文件

  • ls - l的 显示链接的名称和引用的文件

  • 一个符号链接的内容是它引用文件的名称

  • 可以对目录进行

  • 可以跨分区

  • 指向的是另一个文件的路径;其大小为指向的路径字符串的长度;不增加或减少目标文件inode的引用计数;

使用命令

硬链接

	ls 源文件 目标文件

软连接

	ls -n 源文件路径(最好是相对路径) 目标文件

我们在f1所在的目录下创建一个路径文件并进入到该目录下
然后我们创建一个软连接指向f1
这里所说的 相对路径指的是 相对于软连接的路径,而不是当前工作目录的路径。

	ln -s ../f1 lnsfile  
	
	//下面我们创建一个软链接,链接到/etc/issue文件  
	
	ln -s ../../etc/issue lnsfile2 

	//
	ll -i

	lrwxrwxrwx. 1 root root 15 Jul 20 10:03 lnsfile2 -> ../../etc/issue

从上面的结果中可以看出,软连接的文件类型为 l 也就是链接文件。软连接的大写与其指向的路径字符串长度有关,与源文件无关。

如果删除了源文件,该软连接失效.

硬链接和软连接的区别

硬链接的本质是同一个文件多个文件名,软连接相当于快捷方式或者说指针

  • 硬链接创建之后,链接数会加1,软链接不会

  • 硬链接不能针对目录创建,软连接可以

  • 硬链接不能跨分区,跨硬件,软链接可以

  • 硬链接源文件删除了,硬链接不会失效,还是会指向文件数据,软连接源文件删除了,软连接失效。

  • 硬链接的元数据和源文件一致,他们本质上是一个文件。软连接不是,软连接是链接文件,大小会发生变化。



个人博客地址:http://www.pojun.tech/ 欢迎访问