【看表情包学Linux】软硬链接

news2024/7/3 17:27:22

  🤣 爆笑教程 👉 《看表情包学Linux》👈 猛戳订阅  🔥

💭 写在前面:上面我们学到的所有东西,全部都是在内存中的。是不是所有的文件都被打开了呢?不是所有的文件,都被打开的,我们之前研究的是进程打开的文件,是由操作系统去管理文件的动态特性,但是我们还有大量的文件,大多数文件都在磁盘上静静地 "躺着" 的。这批文件非常多、杂、乱,本章我们就要探讨在磁盘上 "躺着" 的文件。然后我们将学习 Inode,带着大家理解文件系统,为下面介绍软硬链接做铺垫。有了对文件系统的深刻了解后再去学习软硬链接,事情会变得简单许多!本章内容较多,让我们速速开始!

📜 本章目录:

Ⅰ. 磁盘基础知识(Disk)

0x00 引入:什么是文件系统?

0x01 磁盘的物理结构

0x02 磁盘的逻辑抽象结构

0x03 CHS 寻址

0x04 逻辑扇区 (LBA)

0x05 IO 基本单位

Ⅱ. 索引节点(Inode)

0x00 引入:理解文件系统

0x01 Inode 概念

0x02 伪删除(inode bitmap: 1 → 0)

0x03 创建新文件时OS会做什么?

Ⅲ. 软硬链接(Symbolic Links & Hard Links)

0x00 Linux 下的快捷方式:软链接

 0x01 创建软链接

0x02 创建硬链接

0x03 软硬链接的删除

0x04 硬连接数

0x05 思考一些问题


Ⅰ. 磁盘基础知识(Disk)

0x00 引入:什么是文件系统?

这些在磁盘上静静 "躺着" 的文件,又杂又乱,我们为什么要让它们躺在那占用磁盘空间呢?

因为这些文件随时可能被打开,那些从来不被访问打开的文件就属于乐色文件,就被清掉了。

 而 有可能被访问的文件就必须保留下来! 我们再举个恰当的例子:

《快递驿站》

这其实很好理解,比如你是一个快递驿站的老板,我们把驿站比作磁盘,而那些包裹比作文件。这些包裹总是要被客户取走的,但是你不知道你的客户什么时候会来取,如果你把包裹扔了,客户来取取不到怎么办,所以你需要把包裹存着。通过编号去记录包裹放在几行几列的柜子,老板存在的最大意义就是可以方便用户迅速的存取快递。

磁盘级别的文件管理,本质工作和快递驿站的老板做的工作是一样的!

对磁盘这个大空间的合理划分,让我们能快速定位查找到指定文件,乃至进行相关后续访问操作。

这就是所谓的 文件系统 (File-Sys) !在前言中我们也说了,这些文件是又多又杂又乱!

小至几 kb,大至几 GB 的都有,文件类型也是各种各样 .jpg, .sh 什么都有,文件所属组,

文件类型,只读或者只写,各种各样的 "可能被打开的" 文件都有!所以我们是需要管理它们的。

" 如果操作系统都不知道文件在哪,那还管个毛线 "

0x01 磁盘的物理结构

如果要理解文件系统,我们不妨把视角从内存中移开 (虽然和内存有关系) ,重点关注磁盘。

磁盘是我们电脑上的唯一的一个机械设备,目前我们的笔记本上可能已经不用磁盘了,而是固态银盘 (SSD) 。相对而言用起来更快,效率更高。固态硬盘是另一种存储的方案,和磁盘的存储差别很大,单价比磁盘大很多。一般 500G 的固态基本上比同等的磁盘要贵个两三百块。

磁盘上存储的基本单位是 扇区 (Sector),一般是 512 字节的。近三十年来,扇区的大小一直是 512 字节,但最近几年正迁移到更大、更高效的 4096 字节扇区,通常称为 4K 扇区。

读写磁盘的时侯,磁头找的是某一个面的某一个 磁道 (Traker),的某一个扇区 。

  • 某一个面 → 哪一个磁头 (Head)
  • 磁道指的是哪一个柱面 → 距离圆心的半径 → 哪一个磁头
  • 扇区是磁道上的一段 → 盘面旋转决定的!

文件系统:什么文件,对应了几个磁盘块。

只要我们能找到磁盘上的盘面,柱面 (磁道)  和扇区,我们就能找到一个存储单元了。

用同样的方法,我们可以找到所有的基本单元。

所以,我们这种在物理上查找某一个扇区的寻址方式,叫做 \textrm{CHS} 地址。

机械式 + 外设 = 磁盘一定是很慢的 (CPU, 内存)

磁盘存储数据,磁性 N/S,改变 NS 极,就是改变了 0 1。

🔺 结论:你的文件数据就在这个盘面上。

0x02 磁盘的逻辑抽象结构

我们可以把对应的盘片,想象成为线性的结构。

扇区,我们把盘片想像成为线性的结构,我们当做数组呢?

定位一个 sector,只要找到下标就行了!对于磁盘的管理,转化成为了对数组空间的管理。类似于数组。磁盘上的每个扇区可以被看作是数组中的一个元素,而扇区的编号可以被看作是数组的索引。在这种情况下,可以使用索引来定位一个特定的扇区,就像在数组中使用索引来访问数组元素一样。磁盘管理的任务就变成了对这个线性结构(即盘片)的管理,包括读取和写入特定扇区的数据。例如,如果要读取或写入磁盘上的第5个扇区,就相当于访问数组中的第5个元素。通过索引,可以准确定位到特定的扇区,并进行相应的读取或写入操作。

这个抽象过程,仍然是 "先描述在组织"。

而这个下标,就是 LBA (logic block arrays), 这是操作系统认为磁盘基本单元的地址,它是一种逻辑块地址。所以,未来你想在磁盘中写入:只需要将 LBA 地址映射转化成 CHS 地址,然后将该内存中的数据配合 CHS 地址写入到磁盘里,至此就完成了写入:

\textrm{LBA}\rightarrow \textup{CHS}

💭 举个例子:假设 LBA 是 1234,1000 ~ 2000 属于第二面,2000~ 3000 属于第三面:

\textrm{LBA}=3234\rightarrow C,H,S

3234/1000=3  (在第一面)

3234%1000=234 (在第二面)

234/20=11,\, \, \, \, 234%20=14

\therefore \, 3234\rightarrow C=11,\, H=3,\, S=14

0x03 CHS 寻址

以前硬盘容量比较小,人们采用软盘的设计结构来设计生产硬盘,

硬盘盘片的每一条磁道都具备相同的扇区数量,由此就产生了 CSH 3D 参数 (Disk Geomentry)

即 磁头数 (Heads),柱面数 (Cylinders) 和 扇区数 (Sectors) ,以及对应的 CHS 寻址模式。

CHS 寻址模式是将硬盘划分为三个部分:磁头 (Heads)、柱面 (Cylinder)、扇区 (Sector) 。

  • 磁头:每张磁盘的正面和反面都有一个磁头,一个磁头对应着一张磁盘的一个面,因此,用第几个磁头就能表示数据在哪个盘面。
  • 柱面:由所有磁盘中半径相同的同心磁道构成,在这一系列的磁道水质叠放在一起,就形成了一个柱面的形状。所以 ——  柱面数 = 磁道数。
  • 扇区:就是将磁盘划分为若干个小的区段,每个扇区虽然很小,但是看上去就像是一个 "扇子",所以称之为扇区,每个扇区的容量为 512 字节。

CHS 寻址的最大容量由 CHS 三个参数所决定:

  • 磁头数最大为 255,用 8 个二进制位存储,从 0 开始编号
  • 柱面数最大为 1023,用 10 个二进制位存储,从 0 开始编号
  • 扇区数最大数为 63,用 6 个二进制位存储,从 1 开始编号

所以,CHS 寻址方式的最大寻址范围如下:

\frac{255\times 1023\times 63\times 512}{1048576}=7.837\, \textrm{GB}\, \, (1M=1048576\textrm{\, Bytes})

0x04 逻辑扇区 (LBA)

INT13:BIOS自带的第13号中断,mov ah,0/int13h复位磁盘;mov ah,2/int 13h读磁盘;mov ah,3/13h写磁盘。DOS 中的最有用,最危险的命令,可直接修改硬盘分区表。

由于 INT13 的限制,三维地址 CHS 的最大值只能为 1024/16/63

容量极限只能达到 1024\times 16\times 63\textrm{ Byte}=52842304 \textrm{Byte}={\color{Red} 504}\textrm{M}

其次,在系统管理文件时记录繁琐的 CHS 是件很费力的事情,效果较低。

然而使用 逻辑扇区 (LBA) 后,可在磁盘读写操作时可以摆脱柱面、磁头等硬件参数的限制。

逻辑扇区,是为了方便操作系统读取写入硬盘数据而设置的,其大小与具体地址,都可以通过一定的公式与物理地址对应。操作系统可以根据 LBA 来读取和写入数据,而无需关心物理地址的具体映射方式。

在 LBA 模式下,操作系统可以把所有的物理扇区都按照某种方式或规则看作是一个线性编号的扇区,从 0 到某个最大值方式排列,并连成一条线。把 LBA 作为一个整体来看待,而不是具体到实际的 CHS 值,这样就只需要用一个序数就能确定唯一的物理扇区,这就是线性地址的由来。显然,线性地址是物理扇区的逻辑地址。

IO 的基本单位是 4 kb,

0x05 IO 基本单位

首先,我们需要知道 I/O 的基本单位 4\, kb。 

磁盘的基本单位是 扇区 (常规为 512 字节),文件系统访问磁盘的基本单位是 4\, kb

① 提高 I/O 效率
② 不要让软件 (OS) 设计和硬件 (磁盘) 具有强相关性,即 解耦合

整体 IO 效率提高,将磁盘的数据拷贝到内存花费的时间并不多,花费多的是在磁盘内部寻找位置的过程,该过程是 寻址过程。不管磁盘是多少转,你是永远无法比得上光电信号的。

什么是解耦合?

解耦合是指将两个或多个系统、组件或模块之间的紧密关联度降低,使它们能够独立演进,互不影响。在软件开发中,解耦合是一种设计原则,旨在减少系统各组件之间的依赖关系,从而提高系统的可维护性、灵活性和扩展性。

解耦合的目的是降低系统中各组件之间的相互依赖程度,使其能够独立进行修改、更新或替换,而不会对其他组件产生影响。当系统中的组件高度耦合时,对一个组件的修改可能会引发对其他组件的连锁反应,导致系统的不稳定和难以维护。而解耦合的设计可以使各组件更加独立,降低系统的复杂性,提高系统的灵活性和可扩展性。

对如何管理文件,变成了对一个小组数据的管理。那么如何对一个组做管理?

Ⅱ. 索引节点(Inode)

0x00 引入:理解文件系统

我们使用 ls -l 时,除了能看到文件名,还能看到文件的 元数据 (Metadata) :

每行包含七列,分别是: 模式、软硬连接数、文件所有者、组、大小、最后修改时间和文件名。

ls -l 做的就是读取存储在磁盘上的文件信息,然后把它们显示出来:

这个元数据除了通过这个方式来读取,还有可以通过 stat 命令看到更多的信息。

在讲解上面这些信息前,我们需要了解 inode 的概念。 

0x01 Inode 概念

\textrm{Linux} ext2 文件系统,下图为磁盘文件系统图(当然了,内核中内存映像肯定有所不同):

磁盘是典型的块设备,磁盘分区被划分为一个个小的 block。

一个 block 的大小是由格式化时决定的,并且不可修改。

例如 mke2fs 的 -b 选项可以设定 block 大小为 1024, 2048 或 4096 字节。

* 注:mke2fs 是一个语法,用于建立 ext2 文件系统。(make ext2 file system)

mke2fs [-cFMqrSvV][-b <区块大小>][-f <不连续区段大小>][-i <字节>][-N <inode数>][-l <文件>][-L <标签>][-m <百分比值>][-R=<区块数>][ 设备名称][区块数]

上图中,启动块 (Boot Block) 的大小是确定的。

 块组 (Block Group) :ext2 文件系统会根据分区的大小划分 Block Group。

  • 每个 Block Group 都有着相同的结构组成。

超级块 (Super Block):存放文件系统本身的结构信息。

  • 记录的信息主要有:block 和 inode 的总量,未使用的 block 和 inode 的数量,一个 block 和 inode 的大小,最近一次挂载的时间,最近一次写入数据的时间,最近一次检验磁盘的时间等其他文件系统的相关信息。
  • 如果 Super Block 的信息被破坏,可以说整个文件系统结构就被破坏了。

 块组描述符 \textrm{GDT} (Group Descripter Table):描述块组属性信息。

块位图 (Block Bitmap):Block Bitmap 中记录着 Data Block 中哪个数据块已经被占用,哪个数据块没有被占用。

inode 位图 (inode Bitmap) :每个 bit 标识一个 inode 是否空闲可用。

 i 节点表:存放 "文件属性" 和 "文件大小","所有者"、"最近修改时间" 等。

数据区:存放文件内容。

计算机在启动时,BIOS(基本输入/输出系统)会首先运行。

BIOS 是计算机主板上的固件程序,用于管理计算机的基本硬件和操作。BIOS包括一系列的自检程序(POST),用于检查计算机硬件是否正常工作。如果检查顺利通过,BIOS会将控制权交给操作系统,让操作系统接管计算机的控制权,进而启动操作系统并加载应用程序。如果检查失败,BIOS会发出声音或闪烁指示灯等提示,以表明出现问题。

Data Blocks:以块为单位,进行文件内容的保存。

Inode Table:以 128 字节为单位,进行 inode 属性的保存。

文件 = 内容 + 属性,所以都是数据,都要数据,Linux 采用的是将内容和属性分开存储的方案。

  • 内容:block 中 4 KB
  • 属性:inode 中就是磁盘上的另一份空间,128 字节。
struct inode {
    int id;
    mode_t mod;
    user name;
    data d;
    ...
}

struct inode i = {};

🔍 查看一个文件的 inode:

块位图 Block Bitmap 记录着 Data Block 中哪个数据块已经被占用,哪个数据块没有被占用。

  • 0:表示未被占用
  • 1:表示已经被占用

因此,我们可以利用比特位的内容来表示是否被占用:

0000 0000 \rightarrow 0001 1001

inode 位图 (inode Bitmap) :表示 inode 块是否被占用,inode bitmap 表征 inode 的使用情况。

块组描述符 \textrm{GDT} (Group Descripter Table):描述块组属性信息,有多少 inode,起始的 inode 编号,有多少 inode 被使用,有多少 block 被使用,还剩多少,你的总 group 大小是多少……

那么,一个 inode (文件, 属性) 如何和属于自己的内容关联起来呢?

inode table 内包括了文件的所有属性,其中有一个 blocks 数组,直接保存了该文件对应的 blocks 编号,我们 通过 blocks 编号就可以找到自己文件的内容。

* data block,4 kb,也可以保存其它块的编号!

struct inode 包括文件所有的属性:

struct inode {
    // 文件的所有的属性
    block[15];
};

block[15] 中,[0,11]  中直接保存的就是该文件对应的 blocks 编号。

直接指向对应的 data blocks 中的某些块,这样就可以找到文件对应的某些内容了。[12,15]  指向一个 datablock,但是这个 datablock 不保存有效数据,而保存该文件所使用的其他块的编号!

" 一个 inode 是可以和多个块建立关联的 "

📌 注意:文件名也算文件的属性,但是 inode 里面并不保存文件名!

就这一点,我们立马就能感受到了一个最终的结论:

Linux 下,底层实际都是通过 inode 编号标识文件的。

要找到文件一定要找到 inode 的编号,就知道找到分区内的哪一个小组,这个组的编号是一个到两万的,可以通过inode编号确定你在哪一个组。

知道 inode 了你知道文件的 inode 编号有没有找到,包括文件的大小文件的权限,都拿到了。

所以,要找到文件就必须找到 inode,找到 inode 就找到了所有。

那谁来帮我找 inode 编号呢?

inode 到现在我们对文件的访问全是文件名,我怎么知道 inode 编号是几呢?

下面我们就要重点谈一谈 Linux 下一切皆文件,目录是文件吗?当然也是文件!

如果目录是文件,那么根据 "文件 =  内容 + 属性" ,目录既然也是文件,那么它的属性也必须得有自己的 inode。一个目录也有自己的 inode 属性,我们目录里面内容对应的又是什么呢?

有文件也有对应的 blocks,目录包括文件类型,文件的所属组,文件的创建大小,

关键是一个目录如果有了inode 这个目录的数据块要放什么呢?

你想一想目录的数据块要放什么?我们在之前的章节中讲过一个关于 目录 权限的问题?但是我们说,进入一个目录需要 \textrm{x} 权限,执行。

但是我们今天不需要谈论 \textrm{x} 了,我们创建一个文件,如果要在目录下 创建文件,touch 文件名

创建一个文件需要的是 w 权限,查看文件名我们需要的权限是 r 权限。

重点理解 w 和 r,既然目录也是文件,那么目录文件也有自己的 inode 也有自己的数据块,它的数据块里放的是 文件名 和 inode 的映射关系!

对我们来说,目录也是文件,也有自己的属性,目录文件里保存的是目录文件和 inode 编号。

文件名:inode 编号的映射关系。文件名和 inode 编号是数据,最终保存在了目录内容中。

Linux 同一个目录下可以创建多个同名文件吗?不行!

所以,文件名本身就是一个具有 \textrm{Key} 值的东西,是一对一的关系。

❓ 当我们创建一个文件,操作系统做了什么?

我们创建一个文件的时候,一定是在一个目录下的。文件名 inode 编号 -> 找到自己所处的目录 data block -> 将文件名和 inode 编号的映射关系写入到对应的目录的数据块中。

这也就解释了为什么 inode 里为什么不保存文件名了,因为文件名在目录中。

❓ 知道自己所处的目录名,是否就能知道该目录的 inode?

如果我们想要知道目录的 inode ,我们需要要到父目录去查找对应关系。因此,知道自己所处的目录下,是不能知道目录的 inode 的。

0x02 伪删除(inode bitmap: 1 → 0)

当我们删除一个文件,操作系统做了什么呢?只需将标记 inode bitmap 由 1 置为 0 即可:

\textrm{bitmap:}\, \, 1\rightarrow 0

所以,这实际上是一个 伪删除

如果我们把文件删了,我们可以恢复这个文件,如果要 恢复文件只需要搞到曾经删除的 inode 值就行了。通过一些工具,将 bitmap 从 0 恢复成 1 就可以了。

当我们执行删除文件操作时,操作系统实际上会在文件系统的目录结构中删除该文件的目录项,并将该文件的 inode 节点中的链接数减 1。如果链接数变为 0,则该文件的数据块将被释放,并将 inode 节点标记为可用状态。

然而,删除文件并不意味着文件的数据就被立即清除,因为该文件可能被其他进程或操作系统本身仍然使用或打开。因此,只有当该文件的所有链接数都为 0 时,文件的数据才会被完全清除。

此外,在某些情况下,操作系统也可能使用一些特殊的工具来覆盖文件的数据,以确保文件内容不可恢复。这种覆盖方式被称为 安全删除彻底删除

恢复的最大难点:文件都删掉了,你怎么知道 inode 是多少呢?Linux 系统为了支持恢复,inode 编号会保存在系统的日志文件中的。恢复有点难度!

实际上 Windows 也是这样的,几乎所有的文件系统删文件都不会真的删文件。 

0x03 创建新文件时OS会做什么?

创建一个新文件,操作系统主要会做如下四个操作:

① 存储属性:内核找到一个空闲的 i 结点 (这里是 263466),内核把文件信息记录到其中。

② 存储数据:该文件需要存储在三个磁盘块,内核找到了三个空闲块,300,500,800。将内核缓冲区的第一块数据复制到 300,下一块复制到 500,最后复制到 800……

③ 记录分配情况:文件内容按顺序 300,500,800 存放,内核在 inode 上的磁盘分布区记录了上述块列表。

④ 添加文件名到目录:新的文件名 abc。Linux 在当前目录中记录该文件,通过内核将入口 (263466, abc) 添加到目录文件,文件名和 inode 之间的对应关系将文件名和文件的内容及属性链接起来。

Ⅲ. 软硬链接(Symbolic Links & Hard Links)

0x00 Linux 下的快捷方式:软链接

我们介绍完 inode 了,我们再看我们刚才介绍的 元数据

七列,分别是模式、软硬连接数、文件所有者、组、大小、最后修改时间和文件名。

上图中,红色圈出的就是 软硬连接数 了,我们刚才说了,可以使用 stat 文件名查看更多:

我们可以看到,我们的 mytest.c 文件的软硬连接数是 1。

🔍 软硬链接的区别:

  • 软链接:是一个独立文件,有自己独立的 inode 和 inode 编号。
  • 硬链接:不是一个独立的文件,它和目标文件使用的是同一个 inode。硬链接就是单纯的在 Linux 指定的目录下,给指定的文件新增 文件名 和 inode 编号的映射关系!

我们可以通过如下命令,创建一个文件的软硬链接:

$ ln -s 文件名 链接文件名    # 创建软连接
$ ln 文件名 链接文件名       # 创建硬链接

(下面我们先来讲软连接的创建,再讲硬链接的创建)

 0x01 创建软链接

我们创建一个软连接,可以使用下面的指令:

$ ln -s 文件名 链接文件名    # 创建软连接

比如我们创建一个 my.txt 文件,我们像创建一个 my.txt 文件的软链接,我们可以:

这就是软连接,my.txt 和 my.txt.soft 的 inode 是不同的:

f:\textrm{my.txt}\, \rightarrow 790915
f:\textrm{my.txt.soft}\, \rightarrow 790917

下面我们来举一个实际的例子来体验软链接有什么实际的用途:

💬 代码演示:vim mytest.c

#include <stdio.h>

int main(void) {
    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");
    printf("hello, soft link...\n");

    return 0;
}

🚩 运行结果如下:

程序正常运行,这里我们在 d1/d2/d3 下直接 ./mytest.exe 就可以运行。

但是,如果我们如果想在外面运行这个程序就会很累,因为它的路径有点深:

太麻烦了,所以这里我们就可以给它建立一个软连接,解脱双手:

$ ln -s ./d1/d2/d3/mytest.exe my.exe

这是不是有点像 Windows 下的 快捷方式?没错!

" 软链接就是 Linux 下的快捷方式 "

上面我们演示的是让软链接链接一个可执行程序,未来我们可以用它来链接头文件、库文件,动静态库,这样就可以不需要让我们冗余的在去某些地方找这些库了。

0x02 创建硬链接

对我们来说,硬链接是什么呢?硬链接其实非常简单!我们创建一个硬链接:

$ ln 文件名 链接文件名       # 创建硬链接

my.txt 和 my.txt.hard 映射的是同一个 inode:

f:(\textrm{my.txt}\, \& \, \textrm{my.txt.hard})\rightarrow 790915

硬链接就是单纯的在 Linux 指定的目录下,给指定的文件新增文件名和 inode 编号的映射关系!

0x03 软硬链接的删除

删除的话可以直接 rm,但是我们还是建议使用专门的 取消链接 的指令:unlink

$ unlink 链接文件名   # 取消链接

举个例子,我们把刚才创建的软链接和硬链接用 unlink 把它们扬了:

 这个 unlink 就是用来取消链接的,但它也可以用来删文件。

0x04 硬连接数

我们先打道回府,重新创建一个硬链接,然后我们重点观察一下下面的 "数字":

我们可以再多建立几个硬链接,你可以看到这个数字的变化:

❓ 什么是硬链接数?

你看这个 inode 编号,是不是有点像指针的概念?

硬链接本质就是该文件 inode 属性中的一个计数器 count。用来标识就几个文件名和我的 inode 建立了映射关系。简而言之,就是有自己文件名指向我的 inode (文件本身) 。

" 软链接就是 Linux 下的快捷方式 "

既然是一个独立的文件,inode 是独立的,软连接的文件内容保存的是指向文件的所在路径。

0x05 思考一些问题

❓ 思考:为什么创建普通文件,硬链接数默认是 1 ?

因为 普通文件的文件名本身就和自己的 inode 具有映射关系,而且只有一个!所以默认的硬链接数为 1。

那为什么目录是 2 呢 ?

我们知道,任意一个目录一定存在一个点或两个点: .   ..

那么 ./ 为什么表示的是当前路径呢?因为 . 表示的就是 mydir,当前所处的路径!   

默认一个空目录创建一个 自己的名字 和 一个点,所以两个文件名指向它,所以是 2。

那么 .. 又是什么呢?.. 指向的是上级路径!这就是为什么我们 cd .. 可以回到上级目录的原因,因为它可以指向上级目录。

📜 尾记:其实,如果没有文件系统的铺垫,想直接理解软硬链接难免有些 "痴人说梦",是非常困难的。但我们讲完了文件系统再去理解软硬链接,你就会发现没有那么难,因为我们是从底层开始,向上去学习的!

📌 [ 笔者 ]   王亦优
📃 [ 更新 ]   2023.5.4
❌ [ 勘误 ]   /* 暂无 */
📜 [ 声明 ]   由于作者水平有限,本文有错误和不准确之处在所难免,
              本人也很想知道这些错误,恳望读者批评指正!

📜 参考资料 

C++reference[EB/OL]. []. http://www.cplusplus.com/reference/.

Microsoft. MSDN(Microsoft Developer Network)[EB/OL]. []. .

百度百科[EB/OL]. []. https://baike.baidu.com/.

比特科技. Linux[EB/OL]. 2021[2021.8.31 

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

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

相关文章

论文投稿技巧

论文的投稿技巧包括会议论文的投稿技巧和期刊论文的投稿技巧。会议论文和期刊论文投稿技巧差别较大&#xff0c;读者需要根据自己投稿的是会议论文还是期刊论文使用不同的技巧。 为了提高会议论文的录用率&#xff0c;需要重点考虑的因素包含如下几方面。 1. 会议的主题 投稿…

【Linux】冯诺依曼体系和操作系统:

1.冯诺依曼体系结构&#xff1a; 1.1体系概述理清&#xff1a; 我们常见的计算机&#xff0c;如笔记本。我们不常见的计算机&#xff0c;如服务器&#xff0c;大部分都遵守冯诺依曼体系。 &#x1f525;我们将冯诺依曼体系结构分为输入设备、输出设备、存储器和CPU 上述部分…

一个混淆Tailwindcss类的工具

一个混淆Tailwindcss类的工具 一个混淆Tailwindcss类的工具 前言方案的寻找如何实现混淆如何使用 1. 安装这2个包2. 执行一下脚本3. 添加 prepare script 在你的 package.json 里4. 注册这个插件 webpackvite 效果预览 核心原理 SSR 场景思考和解决方案 错误与反馈 前言 ta…

Ant Design Pro---【03 UMI中使用MOCK】

Mock 数据 Mock 数据是前端开发过程中必不可少的一环&#xff0c;是分离前后端开发的关键链路。通过预先跟服务器端约定好的接口&#xff0c;模拟请求数据甚至逻辑&#xff0c;能够让前端开发独立自主&#xff0c;不会被服务端的开发所阻塞。 约定式 Mock 文件 Umi 约定 /mo…

SpringData-Redis配置及常用操作

文章目录 1.引入依赖2.yml配置文件3.设置Redis序列化4.使用教程5.操作String数据类型6.操作Hash数据类型7.操作Set数据类型8.操作List数据类型9.操作Sorted Set 数据类型 1.引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId…

史上最烂 spring web 原理分析

盗引下篇spring web spring web、spring web 与 tomcat、映射器与适配器、参数解析器与类型转换器、返回值处理器与消息转换器、异常处理器、ControllerAdvice、spring web 工作流程。 版本 jdk&#xff1a;8spring&#xff1a;5.3.20spring boot&#xff1a;2.7.0 1 spring…

关键词高亮显示浏览器 Edge 插件开发 源码

插件功能 将网页中的关键词高亮显示 项目结构 $ tree . |-- content # 注入到网页中的 js 与 css | |-- content.css | -- content.js |-- icons # 插件用到的图标 | |-- icon128.png | |-- icon16.png | |-- icon32.png | -- icon48.png |-- manifest.json # …

Python+Yolov5电梯口跌倒识别

程序示例精选 PythonYolov5电梯口跌倒识别 如需安装运行环境或远程调试&#xff0c;见文章底部个人QQ名片&#xff0c;由专业技术人员远程协助&#xff01; 前言 这篇博客针对<<PythonYolov5电梯口跌倒识别>>编写代码&#xff0c;代码整洁&#xff0c;规则&#x…

【AGC】applinking服务接入产生崩溃问题

【关键字】 AGC、applinking、崩溃 【问题描述】 开发者反馈在应用中集成了AGC的applinking服务&#xff0c;在打开app时遇到了一些问题。具体如下所述&#xff1a; 在接入app linking后&#xff0c;从浏览器中访问短链接&#xff0c;能正常唤起app, 但app启动后就崩溃了&am…

UAD142A01 3BHE012551R0001使用以太网交叉电缆,您也可以直接连接。

​ UAD142A01 3BHE012551R0001使用以太网交叉电缆&#xff0c;您也可以直接连接。 如何将 MicroLogix PLC 连接到计算机并将程序下载到 MicroLogix 1100 MicroLogix PLC由美国罗克韦尔自动化旗下知名工业自动化厂商Allen-Bradley设计。MicroLogix 1100 主要用于小型工业。我们在…

【视频解读】动手学深度学习V2_02深度学习介绍

1.AI地图 人工智能的地图&#xff0c;x轴是不同模式&#xff0c;由符号学到概率模型 到机器学习&#xff0c;Y轴是我想做的东西&#xff0c;最底下的是感知&#xff0c;我得了解这是什么东西&#xff0c;然后做推理&#xff0c;形成自己的知识&#xff0c;最后做规划。最底层的…

07-Vue技术栈之(组件之间的通信方式)

目录 1、组件的自定义事件1.1 绑定自定义事件&#xff1a;1.1.1 第一种方式1.1.2 第二种方式1.1.3 自定义事件只触发一次 1.2 解绑自定义事件1.3绑定原生DOM事件1.4 总结 2、全局事件总线&#xff08;GlobalEventBus&#xff09;2.1 应用全局事件总线 3、 消息订阅与发布&#…

SwiftUI 极简实现文本摆动弹性动画

概览 SwiftUI 为我们来了界面设计和调试上的便利&#xff0c;只需几行代码我们就能实现一个不错的文本动画效果&#xff1a; 如上图所示&#xff0c;我们在 SwiftUI 中基本还没发力&#xff0c;就实现了文本摆动弹性动画。 这究竟是怎么做到的呢&#xff1f; 无需等待&#…

英文论文(sci)解读复现【NO.7】基于注意机制的改进YOLOv5s目标检测算法

此前出了目标检测算法改进专栏&#xff0c;但是对于应用于什么场景&#xff0c;需要什么改进方法对应与自己的应用场景有效果&#xff0c;并且多少改进点能发什么水平的文章&#xff0c;为解决大家的困惑&#xff0c;此系列文章旨在给大家解读发表高水平学术期刊中的 SCI论文&a…

Loadrunner性能测试(一)

备注&#xff1a;电脑最好安装有IE浏览器 一、下载安装包 链接&#xff1a;https://pan.baidu.com/s/1f5Sw0QK5zrLCU1EbN01evg?pwdbite 提取码&#xff1a;bite 包含的文件有&#xff1a; 二、安装loadrunner 注意&#xff0c;以下教程仅展示需要特别注意的步骤&#x…

PHP学习笔记第一天

前言 作者简介&#xff1a;不知名白帽&#xff0c;网络安全学习者。 博客主页&#xff1a;不知名白帽的博客_CSDN博客-网络安全,CTF,内网渗透领域博主 网络安全交流社区&#xff1a;https://bbs.csdn.net/forums/angluoanquan 目录 PHP语法 基本的PHP语法 PHP的数据类型 PH…

Kubernetes 集群中某个节点出现 Error querying BIRD: unable to connect to BIRDv4 socket

1. 问题描述 Readiness probe failed: calico/node is not ready: BIRD is not ready: Error querying BIRD: unable to connect to BIRDv4 socket: dial unix /var/run/calico/bird.ctl: connect: connection refusedReadiness probe failed: 2023-05-04 22:13:23.706 [INFO]…

LiangGaRy-学习笔记-Day10

1、知识回顾 1.1、rpm依赖报错问题 rpm安装的时候&#xff0c;会有依赖报错rpm安装httpd服务&#xff0c;体现报错 #rpm安装httpd [rootNode1 ~]# rpm -ivh /mnt/cdrom/Packages/httpd-2.4.6-88.el7.centos.x86_64.rpm warning: /mnt/cdrom/Packages/httpd-2.4.6-88.el7.ce…

自己组装的电脑怎么用U盘安装系统操作教学

自己组装的电脑怎么用U盘安装系统操作教学分享。有的用户使用台式机的时候&#xff0c;会自己去进行硬件的组装&#xff0c;但是这样的电脑在安装好了之后&#xff0c;里面还没有系统&#xff0c;需要进行安装。如果你不知道怎么去安装&#xff0c;可以来看看以下的操作方法。 …

HummerRisk 使用教程:源码检测

HummerRisk 是开源的云原生安全平台&#xff0c;以非侵入的方式解决云原生环境的安全和治理问题。核心能力包括混合云的安全治理和云原生安全检测。 本文将介绍HummerRisk中「源码检测模块」的功能&#xff0c;包括如何配置项目源码&#xff0c;以及使用源码检测规则进行安全检…