浅析Linux下的链接文件

时间:2022-10-01 10:56:49

浅析Linux下的链接文件

【摘 要】Linux在其文件系统中引入了链接文件用于方便用户使用和系统管理。本文对Linux下的链接文件的实质、分类、用途进行了分析和综述。

【关键词】Linux;链接文件

0 引言

链接文件在Linux的文件系统中扮演重要角色,而其背后又涉及到索引节点(index node,又称inode)这一概念。索引节点是Linux虚拟文件系统(VFS)的基本概念之一。通过剖析链接文件的实质,理解链接文件的分类与区别,可以让Linux的普通用户和管理员正确而有效的使用链接文件。

1 几个基本概念

要理解Linux下链接文件的实质,需要先理解索引节点(inode)和目录项(dentry)这两个基本概念。

在Linux文件系统中,一个文件除了纯数据本身之外,还必须包含有对这些纯数据的管理信息,如访问权限、文件的属主以及该文件的数据所对应的磁盘块等等,这些管理信息称之为元数据(mata data),保存在文件的inode节点之中。[1]

每个inode都有一个全文件系统唯一的inode号,操作系统内核正是通过inode号而非文件名来识别不同的文件。文件名仅仅是为了方便用户使用而已,内核是通过文件名找到inode,然后通过inode访问实际文件数据的。

虽然每个文件对应了唯一的inode号,但inode号是杂乱而毫无意义的,不方面用户记忆和使用,用户希望对每个文件取一个有意义的文件名。现代文件系统提供的一个基本功能是按名存取,所以还需要建立文件名到inode号的对应,这就引出了目录项(directory entry即dentry)的概念。在Linux文件系统中有一类特殊的文件称为“目录”,目录就保存了该目录下所有文件的文件名到inode号的对应关系,这里的每个对应关系就称为一个dentry。而Linux把所有的文件和目录构建成了一个倒立的树状结构,这样,只要确定了根目录的inode号,就可以对整个文件系统进行按名存取了。

2 链接文件的分类

Linux下的链接文件可以分为硬链接和软链接。

硬链接的实质是现有文件在目录树中的另一个入口。也就是说,硬链接与原文件是分居于不同或相同目录下的的dentry而已,它们指向同一个inode,对应于相同的磁盘数据块(data block),具有相同的访问权限、属性等。[2]简而言之,硬链接其实就是给现有的文件起了一个别名。如果把文件系统比喻成一本书的话,硬链接就是在书本的目录中,有两个目录项指向了同一页码的同一章节。

硬链接的优点是几乎不占磁盘空间(因为仅仅是增加了一个目录项而已),但是这一优点相对于软链接其实并不明显(因为软链接占用的磁盘空间也很少)。另外,硬链接有以下一些局限:1)不能跨文件系统创建硬链接。原因很简单,inode号只有在一个文件系统内才能保证是唯一的,如果跨越文件系统则inode号就可能重复。2)不能对目录创建硬链接。原因我在稍后解释。正因为硬链接的这些局限,加之软链接更加易于管理,所以软链接更加常用。

软链接又称为符号链接(symbolic link),简写为“symlink”。与硬链接仅仅是一个目录项不同,软连接实质上本身也是个文件,不过这个文件的内容是另一个文件名的指针。当Linux访问软链接时,它会循着指针找出含有实际数据的目标文件。同样用书本来打个比方,软链接是书本里的某一章节,不过这一章节什么内容都没有,只有一行字“转某某章某某页”。

3 两种链接文件的区别

软链接可以跨越文件系统指向另一个分区的文件,甚至可以跨越主机指向远程主机的一个文件,也可以指向目录。当创建了一个软链接文件后,它的权限为777,即所有权限都是开放的,实际上你也无法使用chmod命令修改其权限,但是实际文件的保护权限仍然起作用。

软链接还可以指向不存在的文件(可能是原来指向的文件被删除了,或者指向的文件系统尚未挂载,或者最初建立该符号链接的时候就指向了一个不存在的文件等等),此时称这种状态为“断裂”(broken)。与之相对的是,硬链接是不能指向一个不存在的文件的。

另外,在Linux上创建一个指向目录的软链接是允许的,但是却不能创建一个指向目录的硬链接。其实在UNIX操作系统的历史上,对目录创建硬链接曾经是允许的。但人们发现,这样做会出现很多问题,尤其是一些对目录树进行遍历操作的如fsck、find等命令无法正确执行。在《Unix高级环境编程》中提到作者Steven在自己的系统上做过实验,结果是:创建目录硬链接后,文件系统变得错误百出。因为这样做会破坏文件系统的树形结构,可能会使目录之间出现环。

为什么软链接可以指向目录而硬链接不行呢?根本原因在于软链接实质上是一个文件,而硬链接实质上是一个目录项(dentry)。在linux系统中,每个文件(目录也是文件,软链接也是文件)都对应着一个inode结构,其中inode数据结构中包含了文件类型(目录,普通文件,符号连接文件等等)的信息,也就是说操作系统在遍历目录时可以判断出符号连接。既然可以判断出符号连接当然就可以采取一些措施来防范进入死循环了,系统在连续遇到8个符号连接后就停止遍历,这就是为什么对目录符号连接不会进入死循环的原因了。而“硬链接”本质上是“目录项”的同义词。当一个目标第一次被创建,就会为它创建一个目录项,这其实就是硬链接。大多数人常常把“硬链接”联想成为一个已有的对象创建一个额外的目录项,但其实是原来的目录项没有任何特殊,所有的硬链接都是平等的,所以Linux内核没有方法能识别出哪个是“原文件”哪个是“硬链接”。这样对于由于目录硬链接而形成的环就无法进行合适的处理。

4 链接文件的用途

合理的使用链接文件,会对日常使用和系统管理带来一些便利,主要包括以下几方面。

1)保持软件的兼容性

例如,在很多Linux发行版中,/bin/sh文件其实是一个指向/bin/bash的符号链接。为什么要这样设计?因为几乎所有的shell script的第一行都是“#!/bin/sh”,“#!”符号表示该行指定该脚本所用的解释器。#!/bin/sh表示使用Bourne Shell作为解释器,这是一个早期的Shell。在现代的Linux发行版中通常采用Bourne Again Shell即bash,bash是对sh的改进和增强,而早期的Bourne Shell在系统的中根本不存在。为了能够顺利的运行脚本而不必修改shell script,只需要创建一个软链接/bin/sh让其指向/bin/bash。如此一来,就可以让bash来解释原本针对Bourne Shell编写的脚本了。

2)方便软件的使用

比如安装了一个大型软件Matlab,它可能默认安装在/usr/opt/Matlab目录下,它的可执行文件位置在/usr/opt/Matlab/bin目录下,除非你在这个路径加入到PATH环境变量里,否则每次运行这个软件你都需要输入一长串的路径很不方便。此时可以通过在“~/bin”下创建一个符号链接,今后在命令行下无需输入完整路径,只需输入matlab即可。

3)维持旧的操作习惯

比如在SuSE中,启动脚本的位置是放在/etc/init.d目录下,而在RedHat的发行版中,是放在/etc/init.d/rc.d目录下。为了避免因为从SuSE转换到RedHat系统而导致管理员找不到位置的情况,可以创建一个符号链接/etc/init.d使其指向/etc/init.d/rc.d即可。[3]事实上,RedHat发行版也正是这样做的。

4)方便系统管理

在/etc/rc.d/rcX.d目录下的符号链接(X为0~7数字)是一个非常典型的例子。在init.d/目录下有许多用于启动、停止系统服务的脚本,如sshd、crond等。这些脚本可以接受一个参数,代表要启动(start)或停止(stop)服务。为了决定在某个运行级别运行哪些脚本及传递给这些脚本哪些参数,RedHat设计了一个额外的目录机制,即rc0.d到rc6.d的7个目录,每个目录对应一个运行级别。如果在某运行级别下需要启动某服务或者需要停止某服务,就在对应的rcX.d目录下建立一个符号链接,指向init.d/目录下的脚本。

5 结束语

通过阐述链接文件背后的索引节点、目录项等与文件系统设计相关基本概念,分析了硬链接及软链接文件的实质,并对使用链接文件的作用进行了综述。

【参考文献】

[1]鸟哥.鸟哥的Linux私房菜基础学习篇[M].3版.北京:人民邮电出版社,2010: 199-203.

[2]王红.Linux文件系统结构分析[J].潍坊学院学报,2011(2):29-31.

[3]Jeffrey Dean.LPI Linux认证权威指南[M].2版.南京:东南大学出版社,2007:209-210.

上一篇:核电厂定期试验管理系统功能设计 下一篇:“脑机接口”技术及其军事应用