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

news2024/12/24 21:25:45

前言

在上篇博客当中,我们对 文件系统 和 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 。

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

BUUCTF [WUSTCTF2020]find_me 1

BUUCTF:https://buuoj.cn/challenges 题目描述: 得到的 flag 请包上 flag{} 提交。 感谢 Iven Huang 师傅供题。 比赛平台:https://ctfgame.w-ais.cn/ 密文: 下载附件,得到一个.jpg图片。 解题思路: 1、得到一张图…

vue3-组件传参及计算属性

​🌈个人主页:前端青山 🔥系列专栏:Vue篇 🔖人终将被年少不可得之物困其一生 依旧青山,本期给大家带来vue篇专栏内容:vue3-组件传参及计算属性 目录 vue3中的组件传参 1、父传子 2、子传父 toRef 与 toRefs vue3中…

大数据系列15:lightgbm笔记

1. 安装 建议用conda安装。 首先安装miniconda,在官网下载对应的版本。 然后将系统的python和pip定位到miniconda文件夹下。 然后用conda安装lightgbm,在Mac m2芯片上测试可行。(用pip直接安装通不过编译)。 2. 简单case 将lig…

php xml数据转数组两种方式

目录 方法一、可以使用simplexml_load_string()函数将XML数据转换为数组。 方法二、使用PHP内置的DOMDocument类来将XML数据转换为数组的方法 方法一、可以使用simplexml_load_string()函数将XML数据转换为数组。 $xmlData <root><name>John Doe</name>&l…

Cesium 展示——地球以及渲染数据导出(下载)为图片或 pdf

文章目录 需求分析新加需求分析第一种方式第二种方式需求 将 Cesium 球体以及渲染数据导出为 jpg/png/pdf 分析 获取场景 scene 信息,转为image 的 octet-stream 流 进行下载为图片 /*** @todo canvas 导出图片* @param {string} dataurl - 地址* @return {Blob}*/ functio…

杭州银行连接解决方案:集成CRM、用户运营和广告推广系统

自动化与智能化是企业新的增长引擎。在数字化时代&#xff0c;企业需要通过数字化工具来提高效率和效益&#xff0c;这也是杭州银行推出的连接解决方案的初衷。该解决方案集成了CRM、用户运营和广告推广系统&#xff0c;为企业提供全方位的数字化转型支持。 杭州银行连接解决方…

「 高并发系统设计 」 如何提高系统性能

「 高并发系统设计 」 如何提高系统性能 参考&鸣谢 ⾼并发系统如何做性能优化&#xff1f; 玄明Hanko 高并发系统设计和优化的通用方法论 渝言家 文章目录 「 高并发系统设计 」 如何提高系统性能[toc]一、高并发系统设计三大目标高性能高可用可扩展 二、性能优化原则问题导…

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

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

qgis添加xyz栅格瓦片

方式1&#xff1a;手动一个个添加 左侧浏览器-XYZ Tiles-右键-新建连接 例如添加高德瓦片地址 https://wprd01.is.autonavi.com/appmaptile?langzh_cn&size1&style7&x{x}&y{y}&z{z} 双击即可呈现 收集到的一些图源&#xff0c;仅供参考&#xff0c;其中一…

中断方式的数据接收

中断接收简介 回顾之前的代码 之前的代码是 等待标志位RXNE位为1才有数据 进而读取数据存放在变量c中 再根据c变量的数据是为0还是为1进而编写灯亮灭的代码 if语句 但这样的代码明显不符合裸机多任务的编程模型 因为在while中为进程 进程执行的时间不能大于5ms 但是while&…

Linux实验四:shell程序设计: shell控制语句

实验目的 进一步巩固shell程序设计语言基本语法&#xff0c;加深对所学知识理解。 实验内容 要求学生掌握以下内容 (1)条件表达式 (2)判断和分支语句 (3)循环语句 (4)函数 实验内容 1 条件表达式 $ test 10 -gt 5 // 算数表达式 10>5 $ echo $? //显示上述表达…

〔004〕虚幻 UE5 像素流部署

✨ 目录 ▷ 启用像素流插件▷ 打包项目▷ 下载环境包▷ 手动下载▷ 安装信令服务器环境▷ 启动信令服务器▷ 设置启动参数▷ 启动程序▷ 网页运行▷ 开启触控界面▷ 启用像素流插件 打开虚幻启动程序,选择 编辑 后点击 插件在插件列表中搜索 pixel streaming 关键字,勾选后重…

杨传辉:从一体化架构,到一体化产品,为关键业务负载打造一体化数据库

在刚刚结束的年度发布会上&#xff0c;OceanBase正式推出一体化数据库的首个长期支持版本 4.2.1 LTS&#xff0c;这是面向 OLTP 核心场景的全功能里程碑版本&#xff0c;相比上一个 3.2.4 LTS 版本&#xff0c;新版本能力全面提升&#xff0c;适应场景更加丰富&#xff0c;有更…

北邮22级信通院数电:Verilog-FPGA(11)第十一周实验(2)设计一个24秒倒计时器

北邮22信通一枚~ 跟随课程进度更新北邮信通院数字系统设计的笔记、代码和文章 持续关注作者 迎接数电实验学习~ 获取更多文章&#xff0c;请访问专栏&#xff1a; 北邮22级信通院数电实验_青山如墨雨如画的博客-CSDN博客 目录 一.代码部分 1.1 counter_24.v 1.2 divid…

【Flink】Standalone运行模式

独立模式是独立运行的&#xff0c;不依赖任何外部的资源管理平台&#xff1b;当然独立也是有代价的&#xff1a;如果资源不足&#xff0c;或者出现故障&#xff0c;没有自动扩展或重分配资源的保证&#xff0c;必须手动处理。所以独立模式一般只用在开发测试或作业非常少的场景…

Spring Boot集成MyBatis实现多数据源访问的“秘密”

文章目录 为什么需要多数据源&#xff1f;Spring Boot集成MyBatis的基础配置使用多数据源小结 &#x1f389;Spring Boot集成MyBatis实现多数据源访问的“秘密” ☆* o(≧▽≦)o *☆嗨~我是IT陈寒&#x1f379;✨博客主页&#xff1a;IT陈寒的博客&#x1f388;该系列文章专栏&…

TIDB拓扑结构

TiDB Server&#xff1a;SQL层&#xff0c;负责接受客户端的连接&#xff0c;执行SQL解析和优化&#xff0c;最终生成分布式执行计划。TiDB Server为无状态的&#xff0c;可增加节点负载均衡。 PD (Placement Driver) Server&#xff1a;整个TiDB集群的元信息管理模块&#xf…

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

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

010 OpenCV中的4种平滑滤波

目录 一、环境 二、平滑滤波 2.1、均值滤波 2.2、高斯滤波 2.3、中值滤波 2.4、双边滤波 三、完整代码 一、环境 本文使用环境为&#xff1a; Windows10Python 3.9.17opencv-python 4.8.0.74 二、平滑滤波 2.1、均值滤波 在OpenCV库中&#xff0c;blur函数是一种简…

vue3 echarts滑动条datazoom怎么设置圆角

效果图 代码 dataZoom: [// {// type: "slider",// show: val.Ydata.length > 8 ? true : false, //隐藏或显示&#xff08;true&#xff09;组件// backgroundColor: "#1c3030", // 组件的背景颜色。// fillerColor: "#74adb2", // 选…