当前位置: 首页 > news >正文

[Linux]一篇文章带你搞定软硬连接

阅读导览:

  1. 先在windows中先见见软硬连接
  2. 从名字、inode等方面分析软硬连接
  3. 如何实现软硬连接
  4. 硬链接注意事项
  5. 软硬链接都用来干什么
  6. 如何在windows中实现硬链接

在这里插入图片描述

文章目录

  • 概念
  • 简述文件系统
  • windows下的快捷方式--软硬链接的直观体现
  • 角度1:文件名
  • 角度2:文件inode
  • 角度3:链接数
  • 如何实现软硬连接
  • 不要啥玩意都去硬链接
  • 软硬链接常见用途
  • 如何在windows中实现硬链接

概念

软链接:symbol link(又称符号链接,切记不是soft link)

硬链接:hard link

inode   权限	 链接数 所有者 组 大小 最后修改时间 文件名
----  -----	-----	-	----	------------	-----
929767 -rw-rw-r-- 2 sll sll 0 Apr 14 10:27 hardlink
929768 lrwxrwxrwx 1 sll sll 6 Apr 14 10:28 symbollink -> test.c
929767 -rw-rw-r-- 2 sll sll 0 Apr 14 10:27 test.c

如图所示:

我们创建了一个test.c(当然我没有往里面写内容,因为软硬链接和代码无关)。然后分别创建了一个软链接(symbollink)、硬链接(hardlink),使其链接test.c

我们将从以下几个方面来看待软硬链接

  1. 引入:windows下的快捷方式
  2. 文件名
  3. 文件inode
  4. 链接数

对了,补充一句:软硬连接和动静态库的动静态链接没有关系!

简述文件系统

本文在ext2文件系统的概念下叙述,且仅对本文需要了解的知识进行叙述。

  1. 一个inode唯一标识一个文件。

  2. 文件和目录在文件系统下看来都是一样的(也可理解为都是以数据的方式存储在磁盘中),只不过权限不同。 文件没有d权限,目录有d权限。文件存储的内容是数据(比如c代码),而目录存储的内容也是数据,只不过这个数据是其内部的文件名和其对应的inode映射关系

    例:一般文件

    test.c文件中数据:代码(存储在data block中)
    int add();
    double sub();

    例:目录文件

    dir目录下数据:文件名 — inode(均存储在data block中)
    hardlink — 929767
    symbollink — 929768
    test.c — 929767
  3. 磁盘划分成许多个分区,每个分区的inode独立(即:相同分区的inode不重复,不同分区的inode可能重复),这也就决定了硬链接跨越文件系统进行链接的不可实现性

windows下的快捷方式–软硬链接的直观体现

大家对windows下的快捷方式肯定不陌生,我们常常将一个文件执行添加桌面快捷方式的操作,这个操作实际上就对应了软链接。让我们再深入探究一下其中的奥秘!

先来玩玩找不同

在这里插入图片描述

软链接

上图中,左侧是我的typora.exe文件的存储位置、右侧是其对应的桌面快捷方式(软链接)

对,如果你仔细观察,其实桌面也是一个文件(Desktop),创建桌面快捷方式本质上就是将文件软链接一份到Desktop文件夹中(当然,这都是后话,与今天所要探讨的并无太大关联,如果感兴趣的小伙伴可以去深入了解以下)。再提一嘴,为什么他们的大小和占用空间不同,这和他们的data block的大小相关,这里就不过多叙述了。

可以看到

  1. 他们的文件类型不同
  2. 文件所处的位置自然不同,因为创建的是桌面快捷方式,放到了Desktop文件夹中
  3. 文件的大小不同,这是因为对于左侧的文件,其内容是其本来具有的应用程序的数据,而右侧的文件的内容则可以理解为一个索引(这个内容就是为了让你找到左侧的源文件)

在这里插入图片描述

硬链接

上图中,左侧是我的test.txt文件的存储位置、右侧是其对应的硬链接文件link.txt(这里将他们放入了同一个文件夹中了)

如果你这个时候去删掉他们之间的任意一个后,再去打开另外一个,发现内容还是没有变(就好像删除的操作白做了一样),这是由于硬链接的特性,会在后面进行叙述(不同的是,如果你删除了被软链接链接文件,则你会发现软链接就没有用了,打不开对应的源文件)

可以看到

  1. 他们的文件类型相同(对,他们就是相同的,一模一样,删了一个另一个还在)
  2. 他们的存储大小相同(因为他们都是同一个文件,存储大小自然相同)

小结

综上我们先得出一个简单的小结:对于软链接,这个文件指向了我的源文件(其内容就是我源文件的位置);对于硬链接,这个文件中的内容就是我的源文件内容。

这个时候可能有朋友要提出疑问,那我用硬链接难道是把文件拷贝了一份???不!硬链接并不会拷贝文件,因为开销太大,相反它利用了引用计数的思想,来实现链接,听我娓娓道来。

角度1:文件名

回顾开始的bash界面

inode   权限	 链接数 所有者 组 大小 最后修改时间 文件名
----  -----	-----	-	----	------------	-----
929767 -rw-rw-r-- 2 sll sll 0 Apr 14 10:27 hardlink
929768 lrwxrwxrwx 1 sll sll 6 Apr 14 10:28 symbollink -> test.c
929767 -rw-rw-r-- 2 sll sll 0 Apr 14 10:27 test.c

我们可以明显的发现:他们的文件名不同

硬链接的文件名就是我创建时给他命的名:hardlink

而软链接的文件名我创建的时候命名为symbollink,但是创建出来后却显示是:symbollink -> test.c

这没什么,作用其实就是告诉用户这个是软链接还是硬链接(linux下不采用文件名标识文件,所以名字是啥自然不重要)。对,就这。

角度2:文件inode

如果你仔细观察,就会发现硬链接文件的inode和源文件是一模一样的,但是软链接的inode则不同。

文件名inode
test.c929767
hardlink929767
symbollink -> test.c929768

由于inode是文件的唯一标识,所以就表明了:

  • 硬链接创建的链接文件hardlink,本质上就是给test.c这个文件增加了个名字(实际上也是如此,创建的时候会在当前目录的data block中增加一个hardlink929767的映射关系存入其中)。
  • 软链接创建的链接文件symbollink -> test.c,本质上是创建了一个新的文件,而这个新文件的内容是其源文件的路径(大抵是这样的,可能还会有别的内容,但主要内容就是路径)。

如上就能搞清楚为什么inode会有如此变化。

角度3:链接数

inode   权限	 链接数 所有者 组 大小 最后修改时间 文件名
----  -----	-----	-	----	------------	-----
929767 -rw-rw-r-- 2 sll sll 0 Apr 14 10:27 hardlink
929768 lrwxrwxrwx 1 sll sll 6 Apr 14 10:28 symbollink -> test.c
929767 -rw-rw-r-- 2 sll sll 0 Apr 14 10:27 test.c

链接数,又称为:硬链接数。是用来标记某个文件被硬链接了多少个文件(又可以理解为,这个inode被取了多少个别名)。

如上所示:

由于hardlinktest.c都链接到了node=929767这个文件(即,有两个映射关系),所以该文件的链接数=2

同样,inode=929768这个文件,只有symbollink -> test.c这一个映射关系,所以其硬链接数为1

文件的删除问题

前面我们提到,hardlink硬链接到了test.c这个文件,但是我删除他们中的任意一个,另外一个内容不会产生影响。这是因为其内部采用了引用计数的思想。

当我删除一个文件的时候,如果链接数>1,那么就对该链接数进行–,同时删除该文件名和其inode的映射关系;如果链接数==1,那么就删除映射关系的同时,再将其对应inode标识的文件删除(彻底删除,你就再也找不到了。当然你用数据恢复的手段可能还可以找得到,毕竟删除数据的本质就将inode bitmap对应位置为0,这点本文就不展开讲述,其属于文件系统的知识)

所以我们做一下归纳吧:

  • 硬链接:本质上就是一种给inode取别名的方式,即增加了一份新的映射关系
  • 软链接:本质上就是创建了一个新的文件,和touch指令区别不大(当然,我指的是创建文件的本质)

如何实现软硬连接

软链接

ln -s sorcefile linkname
//例如:
ln -s test.c symbollink

硬链接

ln sorcefile linkname
//例如:
ln test.c hardlink

不要啥玩意都去硬链接

首先,你几乎是所有玩意都可以去软链接(大抵是这样的,只不过需要考虑到”断链“的情况,也就是软链接不会强制检查链接到不存在的文件)

但是,硬链接可不是随随便便就可以去链接的

  1. 绝对不能跨文件系统去进行硬链接

    解释原理:

    由于不同的文件系统中,inode编号允许重复,所以如果跨文件系统实行硬链接,就会导致链接到错误的inode,所以要从根源上禁止

    现象展示:

    在这里插入图片描述

    我们先分别在mylinkfs,test下创建一个文件,结果如下:

    //mylinkfs
    12 -rw-r--r-- 1 root root     0 Apr 14 14:04 test.c
    //test
    793090 -rw-rw-r-- 1 sll sll    0 Apr 14 14:21 test.c
    

    可以发现,对于mylinkfs中的inode编号十分的小,这是因为这个分区刚刚创建初始化文件系统+挂载,所以在里面创建的文件的inode都会从低到高分配。这也表明了他们不属于同一个文件系统。

    进行软链接:

    sudo ln -s path/test.c symbollink
    //生成了如下文件
    lrwxrwxrwx 1 root root    26 Apr 14 14:26 symbollink -> ../../home/sll/test/test.c
    

    很明显可以连接成功

    进行硬链接:

    sudo ln ../../home/sll/test/test.c hardlink
    //有如下告警
    ln: failed to create hard link 'hardlink' => '../../home/sll/test/test.c': Invalid cross-device link
    

    告警:无效的跨设备链接(即非法的跨文件系统链接)

    所以实践证明,我们确实不能跨文件系统进行硬链接

  2. 不能去链接目录(树)

    在此之前我们先解释一个现象:为什么每当创建一个目录的时候,他的链接数都不是1,而是2,甚至我该目录里面做了一些操作后,链接数更大了?

    [sll@SFT:~/test$] mkdir testlinkdir; ls -li
    929771 drwxrwxr-x 2 sll sll 4096 Apr 14 14:36 testlinkdir
    

    可见,链接数是2。原因很简单,让我们进入testlinkdir看看

    [sll@SFT:~/test$] cd testlinkdir/; ll
    drwxrwxr-x 2 sll sll 4096 Apr 14 14:36 ./
    drwxrwxr-x 3 sll sll 4096 Apr 14 14:36 ../
    

    对,就是这个./搞的鬼,它硬链接到的也是testlinkdir目录。

    但是这玩意其实很怪,因为你明明能看到系统中有链接到目录树的玩意,比如./,../,但是你就是不能手动去链接目录(OS不让你硬链接):

    [sll@SFT:~/test$] ln ./testlinkdir/ hardlinkdir
    ln: ./testlinkdir/: hard link not allowed for directory //不让你去链接目录
    

    为什么不让去链接?因为这可能会破坏目录树的结构,导致循环引用问题,例如:

    如果我要从/home去遍历整个目录树,如果这里面我的某个硬链接链接到了/home,那么就会导致这个遍历一直死循环,根本出不来。而对于操作系统,它有把握拍着胸脯说:我保证我的硬链接不会产生循环引用问题,你能保证你的不会吗?我直接给你禁掉,想用?没门!!

软硬链接常见用途

硬链接: 主要用于在文件系统中创建副本,使得多个文件可以共享相同的数据和权限。这在许多客户端/服务器环境中非常有用,因为它允许客户端直接访问服务器上的主文件,而不需要将副本下载到本地。此外,硬链接还可以用于确保文件的安全,即使原文件被删除,只要还有硬链接存在,文件的数据就不会丢失。

软链接: 主要用于创建指向另一个文件或目录的路径。它的应用场景非常广泛,比如当需要在不同的目录中使用相同的文件时,只需要在某个固定目录放上该文件,然后在其他目录下使用软链接链接该文件,这样既节省了磁盘空间,又方便了文件的访问。此外,软链接还可以用于访问那些已经被删除但仍然需要引用的文件,或者用于不在PATH中的二进制文件或其他资源。

如何在windows中实现硬链接

windows+x

打开Windows PowerShell,找到你当前的路径,然后打开资源管理器进入对应的路径,一般是:C:\Users\NAME,然后在该目录下右键创建一个.txt文件(这一步不用Windows PowerShell,用常规方法),然后在Windows PowerShell中输入:

//这里我们创建的源文件叫test.txt,链接文件叫link.txt
fsutil hardlink create C:\Users\NAME\link.txt C:\Users\NAME\test.txt 

打开Windows PowerShell,找到你当前的路径,然后打开资源管理器进入对应的路径,一般是:C:\Users\NAME,然后在该目录下右键创建一个.txt文件(这一步不用Windows PowerShell,用常规方法),然后在Windows PowerShell中输入:

//这里我们创建的源文件叫test.txt,链接文件叫link.txt
fsutil hardlink create C:\Users\NAME\link.txt C:\Users\NAME\test.txt 

然后就创建成功了。

相关文章:

[Linux]一篇文章带你搞定软硬连接

阅读导览: 先在windows中先见见软硬连接从名字、inode等方面分析软硬连接如何实现软硬连接硬链接注意事项软硬链接都用来干什么如何在windows中实现硬链接 文章目录 概念简述文件系统windows下的快捷方式--软硬链接的直观体现角度1:文件名角度2&#xff…...

AI常见关键术语

哈喽,大家好,我是小码哥,人工智能技术的快速发展带来了许多专业术语,这些词汇对于理解AI的工作原理和应用至关重要。以下是一些关键的AI术语,以及它们的专业解释和通俗总结。 一、核心概念 人工智能 (AI) 专业解释&am…...

DataX案例,MongoDB数据导入HDFS与MySQL

【尚硅谷】Alibaba开源数据同步工具DataX技术教程_哔哩哔哩_bilibili 目录 1、MongoDB 1.1、MongoDB介绍 1.2、MongoDB基本概念解析 1.3、MongoDB中的数据存储结构 1.4、MongoDB启动服务 1.5、MongoDB小案例 2、DataX导入导出案例 2.1、读取MongoDB的数据导入到HDFS 2…...

HarmonyOS鸿蒙端云一体化开发--适合小白体制

端云一体化 什么是“端”,什么是“云”? 答:“端“:手机APP端 “云”:后端服务端 什么是端云一体化? 端云一体化开发支持开发者在 DevEco Studio 内使用一种语言同时完成 HarmonyOS 应用的端侧与云侧开发。 …...

Quanto: PyTorch 量化工具包

量化技术通过用低精度数据类型 (如 8 位整型 (int8)) 来表示深度学习模型的权重和激活,以减少传统深度学习模型使用 32 位浮点 (float32) 表示权重和激活所带来的计算和内存开销。 减少位宽意味着模型的内存占用更低,这对在消费设备上部署大语言模型至关…...

宝塔面板Docker+Uwsgi+Nginx+SSL部署Django项目

这次为大家带来的是从零开始搭建一个django项目并将它部署到linux服务器上。大家可以按照我的步骤一步步操作,最终可以完成部署。 步骤1:在某个文件夹中创建一个django项目 安装django pip install django创建一个django项目将其命名为djangoProject …...

Android 无线调试 adb connect ip:port 失败

1. 在手机打开 无线调试 使用 adb connect 连接 adb connect 192.168.14.164:39511如果连接成功, 查看连接的设备, 忽略 配对下面的步骤. adb devices如果连接失败: failed to connect to 192.168.14.164:39511如果失败了, 可以杀死一下进程, 然后执行后面的操作 adb kill…...

年龄与疾病c++

题目描述 某医院想统计一下某项疾病的获得与否与年龄是否有关,需要对以前的诊断记录进行整理,按照0-18岁、19-35岁、36-60岁、61以上(含61)四个年龄段统计的患病人数以及占总患病人数的比例。 输入 共2行,第一行为过…...

neo4j-01

Neo4j是: 开源的(社区版开源免费)无模式(不用预设数据的格式,数据更加灵活)noSQL(非关系型数据库,数据更易拓展)图数据库(使用图这种数据结构作为数据存储方…...

正则表达式 速成

正则表达式的作用 正则表达式,又称规则表达式,(Regular Expression,在代码中常简写为regex、regexp或RE),是一种文本模式,包括普通字符(例如,a 到 z 之间的字母)和特殊字…...

21、Lua 面向对象

Lua 面向对象 Lua 面向对象面向对象特征Lua 中面向对象一个简单实例创建对象访问属性访问成员函数完整实例 Lua 继承完整实例 函数重写 Lua 面向对象 面向对象编程(Object Oriented Programming,OOP)是一种非常流行的计算机编程架构。 以下…...

openssl3.2 - exp - class warp for sha3-512

文章目录 openssl3.2 - exp - class warp for sha3-512概述笔记调用方代码子类 - cipher_sha3_512.h子类 - cipher_sha3_512.cpp基类 - cipher_md_base.h基类 - cipher_md_base.cpp备注END openssl3.2 - exp - class warp for sha3-512 概述 前面实验整了一个对buffer进行sha…...

cog predict docker unknown flag: --file

如图: 使用cog predict -i image“link-to-image” 出现docker unknown flag: --file的问题。 解决方法(对我可行):切换cog版本。 这个是我一开始的cog安装命令(大概是下的最新版?)&#xff1…...

SpringMVC接收参数方式讲解

PathVariable 该注解用于接收具有Restful风格的参数,如/api/v1/1001,最终userId的值为1001。 如下代码中,使用name属性可以指定GetMapping中的id名称与之对应,从而可以自定义参数名称userId,而不是使用默认名称id G…...

JavaScript 中arguments 对象详细解析与案例

在JavaScript中,每个函数都有一个内部对象arguments,它包含了函数调用时传递的所有参数。arguments对象类似一个数组,但是它并不是真正的数组,它没有数组的方法,只有length属性和索引访问元素的能力。 以下是对argume…...

消除 BEV 空间中的跨模态冲突,实现 LiDAR 相机 3D 目标检测

Eliminating Cross-modal Conflicts in BEV Space for LiDAR-Camera 3D Object Detection 消除 BEV 空间中的跨模态冲突,实现 LiDAR 相机 3D 目标检测 摘要Introduction本文方法Single-Modal BEV Feature ExtractionSemantic-guided Flow-based AlignmentDissolved…...

【免安装的MATLAB--MATLAB online】

目录: 前言账号的注册图片处理的示例准备图片脚本函数 总结 前言 在计算机、数学等相关专业中,或多或少都会与MATLAB产生藕断丝连的联系,如果你需要使用MATLAB,但是又不想要安装到自己的电脑上(它实在是太大了啊&#…...

Flyway 数据库版本管理

一、Flyway简介 Flyway是一款开源的数据库迁移工具,可以管理和版本化数据库架构。通过Flyway,可以跟踪数据库的变化,并将这些变化作为版本控制的一部分。Flyway支持SQL和NoSQL数据库,并且可以与现有的开发流程无缝集成&#xff0…...

lua学习笔记19(面相对象学习的一点总结)

print("*****************************面相对象总结*******************************") object{} --实例化方法 function object:new()local obj{}self.__indexselfsetmetatable(obj,self)return obj end-------------------------如何new一个对象 function object:…...

视觉SLAM学习打卡【10】-后端·滑动窗口法位姿图

本节是对上一节BA的进一步简化,旨在提高优化实时性.难点在于位姿图部分的雅可比矩阵求解(涉及李代数扰动模型求导),书中的相关推导存在跳步(可能数学功底强的人认为过渡的理所当然),笔者参考了知…...

C++实现分布式网络通信框架RPC(3)--rpc调用端

目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中,我们已经大致实现了rpc服务端的各项功能代…...

【Linux】C语言执行shell指令

在C语言中执行Shell指令 在C语言中&#xff0c;有几种方法可以执行Shell指令&#xff1a; 1. 使用system()函数 这是最简单的方法&#xff0c;包含在stdlib.h头文件中&#xff1a; #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...

无法与IP建立连接,未能下载VSCode服务器

如题&#xff0c;在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈&#xff0c;发现是VSCode版本自动更新惹的祸&#xff01;&#xff01;&#xff01; 在VSCode的帮助->关于这里发现前几天VSCode自动更新了&#xff0c;我的版本号变成了1.100.3 才导致了远程连接出…...

【git】把本地更改提交远程新分支feature_g

创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)

文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...

用docker来安装部署freeswitch记录

今天刚才测试一个callcenter的项目&#xff0c;所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...

【JavaWeb】Docker项目部署

引言 之前学习了Linux操作系统的常见命令&#xff0c;在Linux上安装软件&#xff0c;以及如何在Linux上部署一个单体项目&#xff0c;大多数同学都会有相同的感受&#xff0c;那就是麻烦。 核心体现在三点&#xff1a; 命令太多了&#xff0c;记不住 软件安装包名字复杂&…...

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中&#xff0c;新增了一个本地验证码接口 /code&#xff0c;使用函数式路由&#xff08;RouterFunction&#xff09;和 Hutool 的 Circle…...

听写流程自动化实践,轻量级教育辅助

随着智能教育工具的发展&#xff0c;越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式&#xff0c;也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建&#xff0c;…...

C#中的CLR属性、依赖属性与附加属性

CLR属性的主要特征 封装性&#xff1a; 隐藏字段的实现细节 提供对字段的受控访问 访问控制&#xff1a; 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性&#xff1a; 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑&#xff1a; 可以…...