Linux - 文件系统 - 理解目录 - 理解 软/硬链接

前言

在上篇博客当中,我们对 文件系统 和 inode 做了初步了解,本博客将在上篇博客的基础之上,对于 文件系统当中的目录进行进步一阐述。

Linux - 进一步理解 文件系统 - inode - 机械硬盘-CSDN博客

目录

 一个文件有一个 inode,每一个 inode 都是有自己的 inode 编号(这个inode 编号只在自己当前所在分区当中有效)

inode 的划分是以 分区为单位的,也就是说,各个分区当中的 inode 是独立的,inode 编号也是独立的。

虽然,inode 当中存储了 这个文件的所有属性,但是在这个inode 当中不会存储 文件名的。也就是说,文件名压根就不属于 文件属性

换言之,如果我们想要访问一个文件,如果这个文件名是在 inode 当中存储的,那么对于操作系统来说,用户就要告诉这个 操作系统 ,inode 是多少,才能拿到 文件名。

但是,如果是 小白用户,压根就不知道 inode 的存在,他知道 文件名,而且,我们日常在访问文件,修改文件,查找文件 的基本都是通过 文件名来操作的。 

使用者从来没有关心过 inode 这个是什么,使用者对于操作文件都是通过 文件名来操作的。

而,文件名肯定是有重复的,操作系统如何识别这些重复的文件,其实靠的就是 目录,我们知道,有绝对路径 和 相对路径来找到某一个文件。

所以,其实我们是通过 目录来找到各个文件的。

那么目录是什么呢?


其实目录本质上也是一个文件:

目录也是文件,目录也有自己独立的 inode。也就是说,目录也有自己的 属性。

那么,在目录当中有内容吗

答案是的。那么目录这个文件当中存储的是什么呢

 目录的数据块当中,存储的是 目录当中的文件的 文件名 各个文件对应的 inode 的映射关系

 所以,一个文件的文件名不是存储在 这个文件的属性(inode)当中的,文件的文件名不是这个文件的属性,这个文件的文件名 和 这个文件对应的 inode 的映射关系 是存储在当前文件所以在目录的内容当中的

 所以,比如 ls 这个命令,在查找当前目录下的 文件和 目录的话,其实就是在当前目录的内容当中找到 本目录下的 文件名 和 各个文件映射的 inode 关系,根据命令行参数选项,打印出这个文件对应的信息即可。

所以,如果我们想要进入某一个目录当中,那么这个目录就要有 x 权限;当我们在某一个目录当中 创建一个新的文件,或者是 要删除某一个文件,需要这个目录有 w 权限

 因为,就算我们在一个没有 w 权限的目录 执行路径 当中创建一个了一个新的文件,但是,这个文件的 文件名 和 这个文件对应的 inode 映射关系是不能再 保存在 这个 目录文件对应的数据块当中。

 同样,如果是这个目录是没有 r (读)权限的,那么这个目录当中的文件是不能访问的,因为 要像访问一个文件,或者是修改一个文件,那么就要拿到这个文件的 inode 。但是,因为目录文件是不给读的,所以拿不到想访问文件的inode,那拿不到 inode 怎么访问文件呢?


而像是 绝对路径和相对路径,也是同一个 根目录 或者是 当前目录 文件的数据块当中,一层一层递归的方式来寻找的。

所以,如果我们要想访问 当前目录当中的某一个目录的话,就需要找到这个目录的 inode,才能访问到这个目录文件。

但是,要先找到这个 目录的 inode ,就要在这个目录的上一层的 目录文件的数据块当中找到这个目录文件的 inode映射关系。

到这你可能就会想,那么这不就递归了吗?我们要想找到这个目录的 inode 就要一直往上去递归式的去寻找。

是的,是递归式的寻找,但是,不是无穷无尽的递归,因为 我们从任何路径当中 往上来递归式寻找的话,一定可以找到一个目录 --- 根目录。

所以的目录都是从 根目录 衍生出来的。

所以,绝对路径就是 先递归式的返回遍历到 根目录,再根据 给出的绝对路径 来找到 对应文件

 相对路径就更简单了,只要是当前目录路径已经被找到了,只需要按照相对路径当中给出的路径来进行查找即可。

得出结论:

  • 在Linux 当中,访问任何一个 路径都需要带上路径,可能你在使用 ls 等等这些命令的时候,没有带上路径,但是同样也访问到了 目录文件,或者是文件当中的内容。其实这些命令访问文件也是要 路径的,只不过,我们可以通过设置一些环境变量来 提前保存一些路径,这些我们称之为 -- 默认路径,系统就会默认从 这个路径当中来访问文件,但是其实本质上也是 通过路径来访问到内容的。
     

 而,像上述要像递归到根目录的方式,来查找 文件,这种方式太慢了,所以,在 Linux 当中,会把我们曾经访问过的,或者是经常访问的 若干目录, 已经这些目录当中的若干信息(比如 文件映射的 inode,文件名等等信息),缓存一份。---- dentry缓存

当我们需要访问 缓存当中存在的文件之时,就可以直接从 缓存当中读取到 这个文件的 inode 等等信息,直接访问到这个文件了,不需要再去递归式的寻找 文件位置。

软链接  和 硬链接

 我们先来看是如何创建一个 文件的 软链接 硬链接的:

软链接;

上述就是创建一个 软链接,此时就有一个 text_link 指向 text.c 文件了。

如果你查看这个 text_link 的属性,你会查看到 这个 text_link 有 inode ,说明这个 text_link是一个文件,而且,在这个文件的后面还有一个  数字,你可以看到是1:
 

你可以发现这个 text_link是有 inode的 ,说明这个 text_link是一个 文件,而且,在 这个 text_link 和 text.c 两个文件的访问权限 后面 还有一个 数字1 ,这个数字1 我们在后面 说到 硬链接的时候再叙述

所以,此时也就是相当于是 有一个 text_link 软链接文件指向了 text.c 这个文件。


硬链接:

像上述就生成一个 硬链接文件。

 同时,这个 新生成的 text_link 硬链接文件,也是有 inode 的,但是这个 inode 是和 text.c 文件是一样的,说明这个 硬链接不是一个独立的文件,而且,此时,在 text_link 这个文件的 访问权限符 后面的 数字,变成了2

而且,相信你还注意到 ,我们对应生成目标文件的 硬链接文件的目标文件,也就是 text.c 这个文件。在文件访问权限符之后的数字,在生成 硬链接文件之前,本来是 1 的,但是在生成 硬链接文件之后就变成了2。


对于上述的结果,我们先不做阐述,我们下来看看 生成 软链接文件 和 硬链接文件之间的语法是什么:

其实,都是使用 ln 这个语法,但是吗,如果是软链接文件,需要带上 -s 这个选项参数,其实这里的 -s 就是 Soft 软的这个单词的缩写。

如不带上 -s 这个选项那么,默认就是 硬链接文件的生成方式。、

创建软链接和硬链接的语法:
 

ln -s 被指向文件名 生成的目标指向文件的软链接文件名
ln 被指向文件名 生成的目标指向文件的软链接文件名



ln -s text.c text_link   #生成一个text_link 软链接文件指向 text.c 文件
ln  text.c textlink   #生成一个text-link 硬链接文件指向 text.c 文件

我们先来说说,上述所说的 在文件访问权限符之后的 数字代表的是什么意义

其实这个数代表的意义是代表这个文件当前的硬链接个数。(其实就是 当前 inode 的使用文件的引用计数

 其实,此时,如果我们把一个文件的 软链接文件硬链接文件 ,都创建出来:
 

你会发现,硬链接文件(上图的text-link文件) 和 链接的文件(上图的text.c文件) 的 inode 是一样的。

但是,软连接文件的 inode 和 其他两个文件的 inode 是不一样的。 

硬链接不是一样的独立的文件,因为硬链接文件 没有独立的 inode。


理解硬链接

 因为硬链接文件的 inode 和 链接的文件的inode是一样的。所以,这两个文件的属性应该是一样的

这里也侧面的证明了 ,文件的文件名是不在 文件的inode 当中存储的,而是在目录当中存储的。

而,所谓的建立硬链接,本质上其实就是在特定的 目录的数据块当中,新增 文件名 和 文件和inode 的映射关系。

简答来说,就是在 目标文件所在目录的内容当中(也就是在目录的数据块当中),把 新按照目标文件生成的 硬链接文件的 文件名和 对应的 inode 映射关系,保存到 目标文件所在目录的内容当中。

 如果此时,我们在 硬链接文件存在的情况下,删除 这个硬链接文件链接的 目标文件的话,会出现什么结果呢?

 上述是结果,下述是删除 text.c 文件之前的结果:

发现,就算我们删除了text.c 这个文件,但是,硬链接文件并没有失效,inode 还是和之前一样,跟删除的 目标文件的 inode 保持一致,并没有发生改变

 但是,引用计数 变成了1,因为此时 硬链接个数又变成了1个。

 像上述这种,先创建一个文件的 硬链接文件,然后删除掉这个文件,保存这个文件的硬链接文件,这个操作被称之为 -- 取别名


所以,在每一个 inode 内部,都有一个 作用于 当前 inode 硬链接个数引用计数

 而,在目录当中,保存了 每一个 文件名 对应 映射的 inode 的信息

 可以存在 不同的文件名,映射到同一个 inode 当中。

所以,现在我们可以有一个更好的对于 引用计数的概念,不在是 硬链接文件个数了,而是 有多少个 文件名 映射该 inode

理解软链接

软链接文件当中,你可以发现,其实软链接文件是一个新创建的独立的文件。因为在创建之后,有独立的 inode。所以,软链接不会影响 链接的目标文件的 引用计数。

那么既然有 独立的 inode ,也就意味着有独立的 数据块,也就是说有独立的存储空间,在这个文件当中要存储什么呢?

存储的是 指向的目标文件的路径。

其实你可以理解为 在软链接当中存储的是 ,指向目标文件的 指针通过这个指针可以访问到 这个软链接指向的目标文件

发现,在text.c 当中重定向的字符串 aaaaa ,通过 text-link 这个软链接文件也可以访问到。

 所以,既然存储的是指针,那么就会有 野指针的情况,当我们把软链接指向的 目标文件 删除之时,那么这个 软链接文件当中存储的指针就会失效、

如上所说,从蓝色的软连接文件名,变成了红色的,此时代表的意思就是已经出现连接错误了

 其实,这个软链接特别像 windows 当中 程序的快捷方式

 当我们查看这些 程序的快捷方式的属性的话,可以看见一个 目标的属性:

其实这个就是我们上述所说的,软链接当中存储的是 指向目标文件的 路径。 其实是一样的 。


为什么要有 软硬链接

 我们日常使用的程序软件,其实都不简简单单是一个 xx.exe 这种直接点击就能运行的程序。整个程序一般还是有自己的 配置文件,或者是程序运行所需要的文件数据信息,所以,往往一个程序的 xx.exe 是藏在一个较深的路径当中:
 

而,如果我们想在当前目录下(不在这个程序的 xx.exe 文件下)直接运行这个程序的话,就必须要带上绝对路径或者是 相对路径。

但是类似 D:/ProgramFiles(x86)/Huorong/Sysdiag/bin/xxx.exe 这行来运行这个可执行程序就太麻烦了,所以,可以使用 软连接的方式 创建快捷方式,来调用这个可执行程序
 

 同样,按照上述的方式,我们可以在Linux PATH 环境变量当中创建出我们自己,或者是第三方的 程序的 软链接文件,这样就可以直接 输入 文件名,不用的现去在当前目录下创建 对应的 软链接文件,都可以直接 调用 我们想安装的 程序的可执行文件了
 

此时我们就可以直接,在任何路径下调用这个 我们刚刚安装的 程序了:
 

 所以,这个软件安装到哪里都可以,只要在 PATH 环境变量 指向的 系统默认的 路径目录当中创建了 这个程序的 软链接程序,就可以随时随地调用这个程序了。


其次,当你创建了一个新的目录,那么你会发现,这个目录的 硬链接个数2 个。其实你应该已经猜到为什么了:
 

 在上图当中,就有一组 inode 和 文件名 的关系,就是当前的dir 这个目录文件名 和 这个文件的inode 的映射关系。现在我们进入到这个目录当中,查看这个目录当中所有文件,包括隐藏文件:
 

有一个 "." 作为文件名的 文件,很多读者应该知道,这个 "." 文件,代表的是当前所在 所在目录的这个目录的文件。

也就是说,在 dir 这个目录当中的 "." 这个文件,和 dir 这个目录文件 所映射的 inode 是一样的,两个映射的是同一个 inode,代表的是同一个文件。

而且如上图所示,你可以发现 dir 和 dir当中的 "." 这两个文件名的 inode 是相同的。

所以,这里你就可以理解了 ,为了 每一个目录当中的 "." 文件,都可以代表的是 当前目录文件。

上述也提到了 ".." 两个点的文件名,这个文件代表的是当前目录的 上级目录文件,和上级目录文件共用的是同一个inode。

所以,按照这个推理的话,在上述创建 dir 这个目录 所在目录,应该就有 3 个 硬链接个数了,因为在 dir 当中还有一个 ".." 文件是映射的 这个目录:
 

如上图所示,ln_text 目录就是 dir 所在的目录,是三个 硬链接个数。

 同样你可以查看 "/" 根目录 的 硬链接个数:
 

 发现是一个很大数字,因为在 "/" 目录当中已经创建了很多个 目录了,每一个目录当中都有一个 ".." 硬链接上 "/" ,所以才会有这么多。

所以,往后,如果想知道某一个 目录当中有多少个 有效目录(也就是想上述 dir 这样目录)其实可以像上诉一样查看这个目录的 硬链接个数,该目录的 硬链接个数 - 2 就是这个 目录当中的有效目录。

 Linux 当中的目录结构是一个多叉树,Linux 当中的文件系统是利用 上述的 硬链接方式,来 维持多叉树当中每一个 结点当中的有 parent指针 和 指向当中结点的指针,这样一个关系。我们称之为 -- 路径定位。实现目录间的切换。

然后使用在目录当中存储的 文件名 和 文件名所映射的 inode 来位置当前结点的孩子结点直接的关系。


在上述你可能有疑问,为什么可以直接用一个目录的 硬链接个数来确定其中的 有效目录个数?

就不怕 用户自己使用 ln 这个指令来对 这个目录文件进行 硬链接吗?

其实不怕。因为 目录是不能使用 ln 创建硬链接的

如上所示,我们发现报错了,报错信息是  链接不允许是 目录。 

但是,目录是可以建立 软链接的

 这里需要注意是:如果你想删除某一个 软链接的话,可以使用 rm 命令,但是有的时候是删不掉的,这个时候更多的使用的事 unlink 软链接文件名 这样的方式来进行删除软链接文件的。


为什么Linux 不给 目录建立硬链接?

 我们可以假设一下,然后来考虑为什么。其实很简单,就是一个循环引用计数的问题。

如上图所示,dir 目录文件是 ln_text 目录文件的硬链接,dir 就相当于是我们在某一个目录下 创建的一个ln_text 目录文件的 硬链接文件。

那么在上述 多叉树文件系统当中,如果我想从 ln_text 找到 dir 这个目录的话,从上图当中的红色路径就可以找到,但是,当我们找到 dir 之后,它的 inode 又是 2(和 ln_text 是一样的),所以此时就会回去找到 ln_text 目录, 又回到 最初的起点,但是还是没有找到,所以又会像之前一样往下递归找到 dir 目录·······

这不就是一个循环了吗?

而,上述说过 "." 和 ".." 两个文件不也是建立了 硬链接吗

这两个文件不是用户建立的,是操作系统自己建立的,它在建立之初,因为 这两个文件和自己硬链接的文件 不会像上个例子一样 隔个十万八千里,人家就是表示的当前目录和 上级目录,所以这个在操作系统内部可以实现。但是如果放在很长的 文件系统多叉树结构当中就不好实现了。

换句话说,操作系统自己能够 实现目录的硬链接,本质上其实是 操作系统只相信自己,不相信任何人,包括 root 。

 同样你也可以发现,关于 "." 和 ".." 这两个文件是不能做 搜索操作的吗,只能在 路径定位当中使用。

换言之,操作系统之所以要 才上 循环引用的坑也要 弄出 "." 和 ".." 这两个文件,就是为了引出 相对路径这个概念,让我们更好的使用 文件系统。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/183660.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【面试送分题!“商品分类浏览”如何测试?】

电商项目无论是工作中,还是面试中,都是一个高频出现的词。 面试官非常热衷提问关于电商项目的问题。例如商品分类怎么测试?购物车怎么测试?订单怎么测试?优惠券怎么测试?支付怎么测试?等等。 …

tcp/ip协议2实现的插图,数据结构2 (19 - 章)

(68) 68 十九1 选路请求与消息 函rtalloc,rtalloc1,rtfree (69)

【硬核HeyGen平替】在window平台上使用MyHeyGen

最近在研究HeyGen的平替开源项目,然后发现了MyHeyGen这个项目,但是文档上面并没有说明如果在window平台上使用,考虑到非window平台安装显卡驱动什么的比较繁琐,所以尝试硬着头皮干... 前提 开源项目中所需的环境准备要先准备好 1…

线性空间(也叫向量空间)、线性运算

线性空间、线性运算 线性空间,也称向量空间。 假设是一个非空集合,是一个实数域。 在中定义了一个加法:即对中任何两个元素和,总有中另外一个元素与它们相对应,称为和的和,记作: 在定义了一个…

在全球碳市场中崭露头角的中碳CCNG

在全球气候治理的大背景下,中国碳中和发展集团有限公司(简称中国碳中和)正在成为全球碳交易市场的一个重要参与者。随着国际社会对碳排放的日益关注,中国碳中和凭借其在碳资产开发、咨询与管理等领域的深厚积累,正成为…

机器学习/sklearn笔记:MeanShift

1 算法介绍 一种基于质心的算法通过更新候选质心使其成为给定区域内点的均值候选质心的位置是通过一种称为“爬山”技术迭代调整的,该技术找到估计的概率密度的局部最大值 1.1 基本形式 给定d维空间的n个数据点集X,那么对于空间中的任意点x的均值漂移…

ArgoWorkflow教程(一)---DevOps 另一选择?云原生 CICD: ArgoWorkflow 初体验

来自:探索云原生 https://www.lixueduan.com 原文:https://www.lixueduan.com/posts/devops/argo-workflow/01-deploy-argo-workflows/ 本文主要记录了如何在 k8s 上快速部署云原生的工作流引擎 ArgoWorkflow。 ArgoWorkflow 是什么 Argo Workflows 是…

解决:前端js下载文件流出现“未知文件格式”错误

第一中情况: 出现的问题,前端已经设置了responseType: blob,下载下来还是格式不对。 最后经过排查,后端缺少charsetutf-8,所以前端可以设置编码: 第二中情况: 后端已经设置了charsetutf-8,前…

居家适老化设计第二十八条---卫生间之地漏

以上产品图片均来源于淘宝网,侵权联系删除 居家适老化的地漏是为了满足老年人和身体不便者的需求,使其能够更方便、安全地使用,具有以下特点:1. 防滑设计:地漏表面的材质采用防滑处理,以防止老人在使用过程…

自学编程,用好这几个网站就够了!

如果你要自学编程,一定要收藏好这7个网站,上面免费的优质教程很多,完全可以省去你上万块钱的学费! 话不多说,直接上干货! 第一个,W3school 一个主打图文教程的网站,不管是前端开发…

Java Web 实战 21 - 用 Servlet 实现一个Hello World

用 Servlet 来写一个 Hello World~ 一 . 基本部署方式1.1 创建 Servlet 项目1.2 引入依赖1.3 创建目录1.4 编写代码继承 HttpServlet重写 doGet 方法删除 super 方法加上 WebServlet 注解写业务逻辑 1.5 打包1.6 部署1.7 验证1.8 小结 二 . 更方便的部署方式2.1 Smart Tomcat 的…

首批!创邻科技入选《图数据库金融应用场景优秀案例》

11月11日,“全球金融科技中心网络年会”在第三届全球金融科技大会暨第五届成方金融科技论坛上成功在京举办。会上,北京前沿金融监管科技研究院发布了基于国际标准组织——国际关联数据基准委员会(LDBC)的《图数据库金融应用场景优…

REST教程

越来越多的人开始意识到,网站即软件,而且是一种新型的软件。这种"互联网软件"采用客户端/服务器模式,建立在分布式体系上,通过互联网通信,具有高延时(high latency)、高并发等特点。 …

利用MATLAB进行矩阵运算

一、画出y1/(x3)的函数曲线,x∈[0, 200]。 程序: x0:0.01:200; y(3x).^(-1); plot(x,y) 结果: 二、生成一个信号:xsin(2*pi*t)cos(4*pi*t) 程序: syms t; xsin(2*pi*t).*cos(4*pi*t); fplot(x,[0 pi]); 结果&…

飞书智能伙伴之 AI 数智参谋:先进团队,北极星指标也要遥遥领先

11 月 22 日,飞书在 2023 秋季飞书未来无限大会上正式发布了飞书智能伙伴。作为首批生态伙伴,基于 Kyligence 智能一站式指标平台实现的 AI 数智参谋也正式亮相。这是继 11 月 21 日 Kyligence 产品发布会后,Kyligence 在数据驱动决策智能领域…

医学生秋招攻略,面试时一定要注意这些方面!

医学生别拖了,今年秋招已经过去一波热度了,赶早不赶晚!在筹备第二轮秋招以及明年的春招的医学生一定要注意以下事项。 1.清晰目标 搜集秋招讯息 一定要早点多做准备,想清楚未来的目标,是继续深造还是就业做医生或者是…

Centos Download

前言 CentOS Linux 是一个社区支持的发行版,源自 CentOS git for Red Hat Enterprise Linux (RHEL) 上免费提供给公众的源代码。因此,CentOS Linux 的目标是在功能上与 RHEL 兼容。CentOS 计划主要更改组件以删除上游供应商的品牌…

C++设计模式之工厂模式(中)——工厂模式

工厂模式 工厂模式介绍示例示例使用运行结果工厂模式与简单工厂模式区别 工厂模式 工厂模式在简单工厂模式的基础之上进行了改进。当需要生产的产品种类增加,可以通过新增子类工厂来生产,没有破坏程序设计原则中的开放封闭原则。 介绍 工厂模式先抽象…

九州未来联合联通智网科技发布白皮书,促进车联网融合发展

2023年11月21日,由2023中国5G工业互联网大会组委会、工业和信息化部主办,联通智网科技承办的2023中国5G工业互联网大会——5G车联网与智慧交通创新发展平行会议,在武汉成功举办。 九州未来作为中国联通车联网创新联合体成员单位,受…

Jmeter+influxdb+grafana监控平台在windows环境的搭建

原理:Jmeter采集的数据存储在infuxdb数据库中,grafana将数据库中的数据在界面上进行展示 一、grafana下载安装 Download Grafana | Grafana Labs 直接选择zip包下载,下载后解压即可,我之前下载过比较老的版本,这里就…