当前位置: 首页 > 科技观察

Linux文件系统中的硬链接和面试常见问题

时间:2023-03-14 10:15:49 科技观察

如果你能理解inode的概念,对理解这篇文章会有帮助。inode的概念不清楚没关系,我们会顺带介绍一下。在文件系统的实现层面,我们可以想到两个组成部分:一个是包含数据块的池,池中的数据块大小相等,比如4KB、8KB等;另一个是管理这些数据块的数据库。普通用户访问文件数据时,就是通过上述数据库找到文件对应的数据块。什么是inodeinode是Linux(Unix)操作系统中文件系统的一个概念。inode的全称是indexnode,即索引节点。那么用来索引的inode是什么呢?实际上,inode代表一个文件,用来索引文件数据。以Ext3文件系统为例,它的文件数据是通过间接块来管理的,inode通过间接块树来管理整个文件的数据。图1Ext3间接块数组的组织形式如图所示。inode包含索引信息。通过文件的逻辑地址和inode中的索引信息,可以通过多种方式找到文件特定位置的数据。关于inode和文件系统的更多知识可以阅读本期其他文章,本文不再赘述。需要注意的是,inode中并没有文件名的信息。与文件名相关的信息存储在目录中,文件名与目录中的inodeID有对应关系,如下图。由于两者的对应关系,可以很容易的根据文件名得到inodeID,进而得到inode信息。图2目录中的数据格式什么是硬链接文件的硬链接是指向inode的目录项。硬链接表面上是文件,但文件是在原文件的基础上创建的链接文件。硬链接指向与源文件相同的inode,所以它的数据是完全一样的。与硬链接相比,还有一个软链接的概念。软链接指向的是一个具体的文件,而不是文件的inode,所以当文件重命名时,软链接就会失效。因为软链接原来指向的文件已经不存在了。硬链接不是这种情况。假设如图所示的目录结构,Linux目录下有两个文件file1和file2。目录编程语言中有file2一个指向linux目录中file1的硬链接。这是用户层面的形式,那么文件系统层面呢?在文件系统层面,我们知道文件系统是通过一个inode来表示一个文件(包括目录)的内容。“eBook”目录的inodeID为15,其内容如下图所示,包括Linux、编程语言等子目录,对应的inodeID如图所示。对于包含文件file1和file2的目录“Linux”,inodeID分别为19和20。“编程语言”目录包含文件file2和硬链接file1_hlink。可以看出file1的inodeID和硬链接file1_hlink的inodeID是一样的,都指向19,inode19的内容如下。从上图可以看出硬链接和源文件的对应关系。如何在Linux中创建硬链接前面介绍了很多理论内容,那么在Linux中如何创建硬链接呢?很简单,使用ln命令即可。创建硬链接的命令格式如下。lntarget_filelink_name上面的命令将创建一个名为link_name的硬链接到文件target_file。通过比较,你会发现两者没有任何区别,包括文件内容和属性。如果通过ls-li命令可以看到,两个文件的inodeID相同(第一列的内容),文件的个数都是2(rwx权限后的数字),说明有是指向inode的两个文件名。134195-rw-r--r--2sunnyzhangsunnyzhang0Jul1719:49target_file134195-rw-r--r--2sunnyzhangsunnyzhang0Jul1719:49link_name以下知识点是面试中经常遇到的。面试题,下面的面试题都是硬链接相关的。如果文件有硬链接,删除源文件会怎样?如果存在硬链接,删除源文件不会删除文件的数据。仍然可以通过硬链接访问文件的数据。为什么会这样?这是因为当一个目录项指向一个inode时,inode会增加引用计数。通常引用计数为1,有硬链接时为2,有另一个硬链接时为3。当我们删除一个普通文件(无硬链接)时,我们会先删除目录项中的内容,然后将inode的引用计数减1,如果此时inode中的引用计数为0,则删除inode并删除关联的数据。如果非零,则仅删除目录条目,而不删除相关内容。因此,如果存在硬链接,则可以正常访问文件内容。为什么我们不能为目录创建硬链接?我们可以为目录创建软链接,但是当我们为目录创建硬链接时,会出现如下错误信息:ln:newdir/test_dir:hardlinknotallowedfordirectory为什么我们不能为目录创建硬链接呢??这是因为目录中除了文件相关的内容外,还有一个指向父目录的目录入口,具体如下图所示的“..”目录。如果我们在另一个目录中创建到这个目录的硬链接,内容就会被覆盖,造成混乱。除了造成目录数据混乱外,另一个问题是路径环的形成。至于如何形成路径环,本文不再赘述,大家可以自行思考。能否区分源文件和硬链接?实际上没有任何信息可以区分硬链接和源文件。如果我们没有文件名命名规则的限制,那么我们就无法区分两者。即文件本身也是一个硬链接。134195-rw-r--r--2sunnyzhangsunnyzhang0Jul1719:49target_file134195-rw-r--r--2sunnyzhangsunnyzhang0Jul1719:49link_target_file比如上面的例子,我们可以通过文件名知道哪个是硬链接。但是没有其他信息可以区分。如何找到文件的硬链接?如果你发现一个文件的引用计数大于1,那么这个文件一定有硬链接。那么如何找到这个文件的所有硬链接呢?其实很简单,使用find命令即可。find命令有一个-inum选项,用于查找指定inodeID的文件,如下。find.-inuminode_number今天的内容先到这里。