【linux】linux基础IO(六)软硬链接(软链接,硬链接)

【linux】linux基础IO(六)软硬链接(软链接,硬链接)
小编个人主页详情<—请点击
小编个人gitee代码仓库<—请点击
linux系列专栏<—请点击
倘若命中无此运,孤身亦可登昆仑,送给屏幕面前的读者朋友们和小编自己!

目录


前言

【linux】linux基础IO(五)深入理解文件系统——书接上文 详情请点击<——,本文会在上文的基础上进行讲解,所以对上文不了解的读者友友请点击前方的蓝字链接进行学习
本文由小编为大家介绍——【linux】linux基础IO(六)软硬链接(软链接,硬链接)

一、如何建立文件之间的软硬链接

软硬链接其实是一个统称,将其进行分开叫做软链接,硬链接,下面小编就带领大家看一下如何在指令层面建立文件之间的软链接,硬链接
进行软链接以及硬链接的前提是要有一个已存在的文件才能进行对应的软硬链接

建立文件之间的软链接

  1. 这样软链接就链接完成了,这时我们使用 ls -l -i 指令去查看文件的inode编号,发现软链接文件sort-link和file.txt一样都有自己独立的inode编号,文件有inode编号就代表着文件有对应的inode,即有独属于自己文件的属性
  2. 因此软链接文件是一个独立的文件,因为它有自己独立的inode

ln -s 被软链接的文件 进行软链接的文件,使用前面的指令即可建立文件之间的软链接,其中 -s选项是代表着soft即柔软的意思,用来表示该指令进行软链接

在这里插入图片描述

建立文件之间的硬链接

  1. 这样硬链接就链接完成了,这时我们使用 ls -l -i 指令去查看文件的inode编号,发现硬链接文件hard-link没有自己独立的inode编号,而是和被硬链接文件test.txt共用同一个inode编号921771,那么表示硬链接文件hard-link没有属于自己的inode,文件没有属于自己的inode编号那么代表文件没有独属于自己的inode,也就意味着没有独属于自己的属性
  2. 因此硬链接文件不是独立的文件,因为它没有自己独立的inode
  3. 同样的这也侧面说明文件名并不属于inode中的文件属性,因为如果文件名属于文件属性的话,那么硬链接文件名hard-link应该和被硬链接的文件名test.txt相同,但是此时两者的名称并不相同,所以说明文件名不属于inode中的文件属性

ln 被硬链接的文件 进行硬链接的文件,使用前面的指令即可建立文件之间的硬链接,观察,这条指令中没有-s选项,说明如果不带-s选项,那么ln指令默认就是进行的文件之间的硬链接

在这里插入图片描述

二、深入理解软硬链接

如何理解软链接

  1. 软链接是一个独立的文件,它具有独立的inode,同样也有独立的数据块,数据块里面保存的是指向文件的路径,

如果要删除软链接文件,那么使用unlink 软链接文件,即可进行删除

在这里插入图片描述

软链接文件中存储着指向文件的路径,那么也就是说,我们可以使用软链接文件去查看指向文件的内容,此时soft-link对file.txt文件进行了软链接,下面我们向指向文件file.txt中追加重定向输入内容,那么这时候我们就可以通过soft-link查看file.txt的内容

在这里插入图片描述

此时对应的C:\Program Files\ToDesk即为实际应用程序存放的位置,桌面的快捷方式存储了这个路径,并且通过这个文件路径就可以找到实际的应用程序打开,这样用户就不再需要亲自去执行的文件路径下打开应用程序了,将这个工作交给快捷方式,即软链接,便捷了用户

在这里插入图片描述

软链接相当于windows中的桌面上的快捷方式,如下windows桌面上中的应用实际上都不是真正的应用程序的存放位置,windows桌面上的应用都是快捷方式,即一个它实际上就是一个文件路径,加上图形化界面的一层外包装而已,我们选中快捷方式,鼠标左击,点击显示更多选项,点击打开文件所在位置

在这里插入图片描述
在这里插入图片描述
软链接的应用场景
  1. 为什么要用软链接?也就是软链接的应用场景,例如:当可执行文件的文件路径很深的时候,我们想在当前路径下直接执行文件路径很深的可执行文件,那么在当前路径下建立一层软链接指向文件路径很深的可执行文件即可
  2. mytest.c的代码如下,代码的作用是打印语句hello soft link

演示一下,我们在当前路径下新建一个mytest.c文件,将它编译一下形成可执行文件mybin.exe

在这里插入图片描述
#include<stdio.h>intmain(){printf("hello soft link\n");printf("hello soft link\n");printf("hello soft link\n");printf("hello soft link\n");printf("hello soft link\n");return0;}
运行结果如下
  1. 为什么软链接文件仅仅通过文件路径就可以访问指向文件的文件内容或者执行指向的可执行文件(应用程序)?软链接文件的数据块中存储的是指向文件的文件路径,通过文件路径就可以向上递归到根目录找到根目录的inode,再向下递归找到指向文件的文件名和文件对应的inode编号的映射关系,这样就找到了指向文件的inode编号,通过这个inode编号就可以找到指向文件的inode结构体访问文件的属性,并且inode结构体中还有数据块块号数组,这样就可以遍历数据块块号数组,通过对应的数据块块号访问文件的内容了,软链接文件通过文件路径可以访问指向文件的属性和文件的内容,自然就可以访问指向文件的文件内容或者执行指向的可执行文件(应用程序)了
  2. 同样的我们也可以通过软链接的形式,将我们的可执行程序放在系统指令的路径中,这样我们执行自己的文件也不需要带路径,而是直接由系统在系统指令的路径中搜索我们软链接文件进行执行

那么此时小编使用pwd先查看一下当前路径的绝对路径,并且tree查看一下bin的目录结构,进而我们的可执行程序mybin.exe相对于当前目录的路径就出来了,那么此时将当前路径的绝对路径和mybin.exe的相对当前路径的路径进行拼接就得到了可执行程序mybin.exe的绝对路径,此时使用ln -s 被软链接的文件 进行软链接的文件,在系统的指令目录/usr/bin下创建一个my.exe的软链接文件,当然向系统的指令路径下创建文件需要权限,小编当前用户是普通用户,权限不够所以sudo提权一下即可执行,这样我们就可以在命令行中不带路径直接通过软链接文件执行可执行文件mybin.exe了

在这里插入图片描述

首先我们使用$PATH看一些系统指令的路径,那么小编就打算将软链接文件放到 /usr/bin/ 这个路径下

在这里插入图片描述

同样的在系统库中同样也有诸多的软链接的使用,或是对文件路径有要求,或是对文件明明有要求,我们可以使用 ls -l /lib64/ 指令进行查看

在这里插入图片描述

今天,我们有软链接了,可以直接在当前路径下对这个应用程序进行软链接,软链接文件中存储着应用程序的路径,那么我们就可以直接通过软链接文件执行可执行文件

在这里插入图片描述

如果我们没有软链接的话,如果想要在当前目录下执行应用程序的话,要写很长的路径才能执行应用程序,不可谓不麻烦

在这里插入图片描述

在一个正规的项目中,通常进行多文件管理,通常有一个配置文件,并且可执行文件的路径通常都放的很深,小编建立一个conf作为一个虚拟的配置文件,递归式建立一个较深的文件目录,将我们的应用程序放到这个较深的文件目录中

在这里插入图片描述

如何理解硬链接

  1. 硬链接不是一个独立的文件,因为它没有独立的inode
  2. 此时原文件file.txt被删除,只留下了硬链接文件hard-link,并且硬链接文件的hard-link的文件属性中的硬链接数变成了1,并且inode编号仍然保持不变,代表着此时inode以及数据块,即原文件的文件属性和文件内容变成了硬链接文件hard-link的了,是不是有点类似于小说情节中的夺舍过程,其实这里更像的是c++中的引用,硬链接可以让多个文件名对应同一个inode
  3. 因此所谓建立硬链接,本质就是在特定目录的数据块中新增文件名和指向的文件的inode编号的映射关系
  4. 任何一个文件,无论是目录,还是普通文件都有inode,每一个inode结构体内部,都会有一个引用计数的计数器,叫做硬链接数,用来表征有多少个文件名指向我
  5. 目录里面保存的是 文件名:inode编号 的映射关系,如下,这种映射关系,文件名映射inode编号,inode编号对应的是inode,即文件名指向inode,那么文件名就类似于指针的作用一样

通过上面的演示我们可以看出原文件file.txt中的硬链接数是1,当我们使用hard-link硬链接源文件file.txt之后,源文件file.txt的硬链接数变为2,同时硬链接文件hard-link的硬链接数也为2,此时小编将原文件file.txt删除一下,看看会发生什么

在这里插入图片描述

下面小编带量大家认识一下inode中的文件属性中的一个引用计数,即硬链接数

在这里插入图片描述
文件名1:inode编号12345 文件名2:inode编号12345 文件名3:inode编号12345 文件名4:inode编号12345 
硬链接的应用场景
  1. 为什么要有硬链接?那么也就是回答硬链接的应用场景有哪些,举例:通常用来进行路径定位,采用硬链接,可以进行目录间的路径切换
  2. 读者友友可以先思考一下,为什么目录dir的硬链接数是2???有点出乎我们的意料,或许我们之前并没有注意过目录文件dir的硬链接数
  3. 相信聪明的读者友友早已经想出原因了,首先我们应该清楚上级目录是谁,当前目录dir的上级目录是lesson26,它存在于哪一个目录下?lesson26这个目录文件存在于lesson这个目录下,对于lesson26文件本身这是第一个硬链接数,接着是lesson26这个目录中存在一个当前目录 . 它也是lesson26的硬链接文件,即这是第二个硬链接数,那么接下来是dir目录中的上级目录 … 就是指的是上级目录lesson26,这是第三个硬链接数,此时我们才搞清楚lesson26的硬链接数究竟是怎么来的
  4. 其实unlink的本质就是在引用计数层面上减少一个文件的引用计数(硬链接数),此时软链接文件soft-link的引用计数是1,那么进行减一之后,文件的引用计数为0,如果引用计数减到0,那么此时删除文件
  5. 此时小编使用unlink删除硬链接文件hard-link,此时硬链接文件的引用计数(硬链接数)减一,即本来的2减为1,此时引用计数不为0,因此不会删除文件,即不会删除文件的文件属性以及文件数据,即对应的inode和数据块,但是此时引用计数为1,说明只能有一个文件名指向inode,而且unlink是对硬链接文件进行删除的,所以此时就会在当前目录的数据块中删除硬链接文件与inode编号的映射关系,所以此时我们就可以观察到硬链接文件文件名hard-link没有了,但是此时硬链接文件hard-link对应的inode编号还在,即此时由普通文件file.txt对应inode编号,即此时inode就独属于普通文件file.txt
  6. 此时我们再使用unlink删除普通文件file.txt,此时普通文件file.txt的引用计数(硬链接数)为1,那么unlink会在引用计数层次上减少文件的引用计数,即此时普通文件file.txt的引用计数就从1减到了0,此时文件的引用计数为0,那么就会进行删除文件,根据inode编号从inode表中找到inode,找到inode结构体的数据块块号数组,将数据块块号数组中的数据块块号遍历,将数据块块号在数据块位图中将对应比特位位置上的内容置为0,表示数据块未使用,即数据块可被覆盖,再通过inode编号在inode位图中对应比特位位置上将inode置为0,表示inode编号不存在,此时文件就被删除了,即文件的inode以及数据块就被删除了(这里的删除仅仅是指在对应的位图结构体将对应比特位的位置上的内容置为0,表示删除,即可覆盖),同时还要在当前目录的数据块中删除硬链接文件与inode编号的映射关系,所以此时我们就可以观察到普通文件file.txt没有了,但是并且与普通文件映射的inode编号也不存在了

同样的unlink也可以用来删除硬链接文件,如下,我们先创建一个普通文件file.txt,那么使用ln 被硬链接的文件 硬链接的文件,对普通文件file.txt进行硬链接,此时普通文件file.txt以及硬链接文件hard-link的inode编号一样,那么说明两个文件名对应的是同一个inode

在这里插入图片描述

正好借助这个硬链接数,此时我们扩展一下删除软链接的unlink是底层是什么,使用ln -s 被软链接的文件 软链接的文件,让软链接指向目录文件之后,小编再使用unlink 软链接文件,即使用unlink删除软链接文件

在这里插入图片描述

同样的我们切换到根目录,那么利用根目录的硬链接数,我们可以知道在根目录下有多少个目录文件,因为根目录下的目录文件都会维护一个硬链接文件 … 所以根目录下有多少个目录文件,就会有多少个链接到根目录的硬链接文件 … 由于根目录自身也是一个硬链接数,并且根目录中还会维护一个当前目录 . 那么对于当前目录也是一个硬链接文件,也是一个硬链接数,所以将根目录的硬链接数减去2,我们就可以得出根目录下有多少个目录文件

在这里插入图片描述

如下图,此时我们使用 … 退回上级目录,查看一下上级路径的硬链接数为什么是3呢?读者友友可以先思考一下

在这里插入图片描述

相信聪明的读者友友已经想到了原因,如下,因为dir目录里面有隐藏的当前路径 . 这个当前路径 . 的inode编号和dir目录的inode编号是相同的,说明当前路径 . 是一个硬链接文件

在这里插入图片描述

如何理解呢?下面跟随小编的视角进行学习即可,首先我们来看小编在当前目录下创建的目录dir并且查看当前目录下的目录文件属性

在这里插入图片描述
硬链接能否链接目录,为什么?
  1. 通过上面的实例,小编对目录文件进行了硬链接,可是操作系统不允许我进行硬链接,有的读者友友心中可能会想,小编小编,你这是普通用户,肯定是权限不够,那么此时小编使用sudo进行提升权限再对目录文件进行硬链接,此时操作系统依旧不允许我对目录文件进行硬链接
  2. 很奇怪,你操作内部明明有对目录文件进行链接的例子啊,当前目录 . 上级目录 … 都是最好的证明啊,为啥你这个坏操作系统不让我进行硬链接目录文件,而你自己却对目录文件硬链接的挺开心?
  3. 假设操作系统允许我们随便对目录建立硬链接,此时假设小编在4号目录下,使用ln / root 对根目录建立硬链接,那么由于 / 根目录文件对应的inode编号,在大多数操作系统中都进行了特殊处理设置为了2,那么此时在4号目录下就会有一个root硬链接文件与inode编号2建立映射关系,同时4号目录下还有一个test.txt文件
  4. 那么我们的目的就是使用find指令从根目录下开始遍历多叉树结构的文件系统,根据test.txt文件名搜索test.txt文件,此时操作系统从根目录开始搜索根目录路径下的目录,开始搜索1号目录,没找到,继续去找2号目录,进入2号目录,去搜索2号目录,找到,继续去找2号目录下的4号目录,遍历到4号目录下的root目录了,虽然test.txt就在4号目录下,但是test.txtq前面有一个root目录,此时遍历搜索进入root目录,由于root目录是对 / 根目录的硬链接,root目录对应的inode编号对应的2,所以去对应为2的inode中找文件路径,由于inode编号为2对应的是 / 根目录的inode,所以inode中会存储根目录的路径,那么此时从编号为2的inode中取出文件路径,就会取出根目录的文件路径,那么此时势必会进入root目录,那么此时就直接返回根目录了,又重复上述操作继续去搜索,那么这不就死循环式的搜索了,即造成了环路问题,所以操作系统绝对不会这样的事情发生,所以就禁止用户对目录文件进行硬链接
  5. 小编,小编,我还有一个疑问,不是当前目录下还有会两个隐藏文件,即当前目录 . 以及上级目录 … 为什么使用find搜索文件的时候,不会搜索当前目录下的两个隐藏文件,即当前目录 . 以及上级目录 … 呢?很简单,如果搜索了那么不就死循环了,所以操作系统势必会再次做特殊处理,使用find搜索文件的时候不去搜索当前目录下的两个隐藏文件,即当前目录 . 以及上级目录 … 此时就没有任何问题了
  6. 那么为什么操作系统要费尽心思的自己做对目录文件的硬链接呢?即实现当前目录下的两个隐藏文件,即当前目录 . 以及上级目录 … 因为只有这样,我linux操作系统才更好用,如果没有当前目录下的两个隐藏文件,即当前目录 . 以及上级目录 … 那么此时你无论是想要进入一个文件,或者创建一个文件,即进行文件操作增删查改的时候都要使用绝对路径,从根目录下一个一个目录的写到当前目录,那么此时使用就不方便了,linux操作系统的存在就是为了服务用户,如果用户认为你这款操作系统不好用,那么使用你这款操作系统的用户群体很少很少,那么这款操作系统也就没有了存在的意义,所以linux操作系统必须设计出当前目录下的两个隐藏文件,即当前目录 . 以及上级目录 … 为用户提供便捷性的服务,并且限制用户对目录进行硬链接,限制同样也是一种保护,避免了用户对目录进行硬链接造成诸如find搜索文件造成的死循环式搜索,即避免了环路问题的发生,只有这样才可以保证操作系统更安全,高效,稳定的被用户使用

很简单,因为操作系统不相信任何人,我们知道操作系统的文件系统是一个多叉树的结构,如果让用户随便对目录文件进行硬链接,那么诸如使用find查找按文件名查找文件的时候,就会出现死循环,即造成环路问题

在这里插入图片描述

既然通过上面的例子,硬链接可以链接普通文件file.txt,那么硬链接可以链接目录文件吗?下面小编就带领大家尝试一下

在这里插入图片描述

总结

以上就是今天的博客内容啦,希望对读者朋友们有帮助
水滴石穿,坚持就是胜利,读者朋友们可以点个关注
点赞收藏加关注,找到小编不迷路!

Read more

超全超详细!JDK 安装及环境配置(Java SE 8 保姆级教程)

超全超详细!JDK 安装及环境配置(Java SE 8 保姆级教程)

一、JDK 简介 JDK(Java Development Kit)是用于开发 Java 程序的工具包,包括编译器 javac、Java 运行环境(JRE)以及各种开发工具。安装和配置 JDK 是学习和使用 Java 编程的第一步,以下是 Java 和 JDK 的具体区别与关系: 名称功能关系Java编程语言和平台Java 是一种语言,而开发 Java 应用程序需要 JDK 工具包。JDKJava 开发工具包(包含 JRE 和开发工具)JDK 是为开发 Java 程序提供支持的工具集合,开发时离不开它。JRE(Java Runtime Environment)Java 运行时环境,用于运行

By Ne0inhk
【JAVA全栈项目】弧图图-智能图床SpringBoot+MySQL API接口结合Redis+Caffeine多级缓存实践解析

【JAVA全栈项目】弧图图-智能图床SpringBoot+MySQL API接口结合Redis+Caffeine多级缓存实践解析

文章案例具体代码链接:https://github.com/whltaoin/hututu 提交版本:e67453a26f0bbe78ce075a550bafb01ba82aa9ff 简言 在后端开发中,API接口是服务间通信的核心载体,而数据存储与缓存策略则直接决定了接口的性能与稳定性。Spring框架凭借其强大的生态成为API开发的首选,MySQL作为关系型数据库提供了可靠的数据持久化支持。当系统并发量提升时,单一数据库架构易出现性能瓶颈,此时引入Redis(分布式缓存)与Caffeine(本地缓存)构建多级缓存体系,成为优化性能的关键方案。本文将从基础实现出发,深入探讨多级缓存的优势、劣势、适用场景及实践注意点。 文章目录 * 简言 * 一、基础架构:Spring+MySQL实现API接口 * 1.1 核心组件与依赖 * 1.2 核心实现流程 * 二、多级缓存:Redis+Caffeine的组合逻辑 * 2.1 组件特性对比 * 2.2 多级缓存工作流程 * 三、多级缓存的优势与劣势

By Ne0inhk
【Java篇】无形至有形,法与道的编织:类与对象初探

【Java篇】无形至有形,法与道的编织:类与对象初探

文章目录 * 类和对象(上) * 一、面向对象的初步认知 * 1.1 什么是面向对象 * 1.2 面向对象与面向过程 * 二、类定义和使用 * 2.1 简单认识类 * 2.2 类的定义格式 * 2.3 小练习 * 2.3.1 定义一个狗类 * 2.3.2 定义一个学生类 * 三、类的实例化 * 3.1 什么是实例化 * 3.2 类和对象的说明 * 四、this引用 * 4.1 为什么要有 this 引用 * 4.2 什么是 this 引用

By Ne0inhk
Java 大视界 -- Java 大数据机器学习模型在金融风险管理体系构建与风险防范能力提升中的应用(435)

Java 大视界 -- Java 大数据机器学习模型在金融风险管理体系构建与风险防范能力提升中的应用(435)

Java 大视界 -- Java 大数据机器学习模型在金融风险管理体系构建与风险防范能力提升中的应用(435) * 引言: * 正文: * 一、金融风控的技术选型逻辑:为何 Java 是核心基石? * 1.1 金融风控的核心技术诉求 * 1.2 Java 生态在金融场景的不可替代性 * 1.3 大数据 + 机器学习的技术融合架构 * 二、核心落地:Java 大数据 + 机器学习的全链路实现 * 2.1 数据层:金融级数据治理(风控的 “生命线”) * 2.1.1 核心痛点与解决方案(真实项目数据) * 2.1.2 实战代码:Java 数据清洗工具类(Spark SQL 集成,可直接运行)

By Ne0inhk