【linux深入剖析】深入理解软硬链接 | 动静态库的制作以及使用

news2024/12/24 8:48:33

🍁你好,我是 RO-BERRY
📗 致力于C、C++、数据结构、TCP/IP、数据库等等一系列知识
🎄感谢你的陪伴与支持 ,故事既有了开头,就要画上一个完美的句号,让我们一起加油

在这里插入图片描述


目录

  • 1.理解软硬链接
    • 1.1 操作观察现象
      • 软链接
      • 硬链接
    • 1.2 软硬链接的原理
      • 测试硬链接
      • 测试软链接
    • 1.3 软硬链接的应用场景
      • 1.3.1软链接
      • 1.3.2 硬链接
  • 2.动静态库
    • 2.1 动静态库的制作和使用
      • 准备工作
      • 生成静态库
      • 生成动态库
    • 2.2 将自己的库打包给别人


1.理解软硬链接

软链接和硬链接是在Linux系统中常见的文件链接方式。

软链接(Symbolic Link): 软链接是一个指向目标文件或目录的特殊文件,类似于Windows系统中的快捷方式。软链接可以跨文件系统,可以链接到目录,也可以链接到文件。软链接的特点是:

  1. 软链接文件有自己的inode和文件名,但是数据块内容是指向目标文件的路径。
  2. 删除软链接不会影响目标文件。
  3. 软链接可以跨文件系统,即可以链接到不同的磁盘分区。

硬链接(Hard Link): 硬链接是指多个文件名指向同一个inode,它们共享同一份数据块内容。硬链接的特点是:

  1. 硬链接文件和目标文件具有相同的inode和数据块内容。
  2. 删除任意一个硬链接文件不会影响其他硬链接文件和目标文件。
  3. 硬链接只能链接到文件,不能链接到目录。
  4. 硬链接不能跨文件系统,即只能在同一个磁盘分区内创建。

1.1 操作观察现象


指令ln -s

ln -s是Linux系统中的一个命令,用于创建软链接(symbolic link)。软链接是一种特殊的文件,它指向另一个文件或目录。通过软链接,可以在不改变原始文件或目录位置的情况下,创建一个指向它的链接。

使用ln -s命令创建软链接的语法如下:

ln -s <原始文件或目录路径> <链接文件路径>

  • 其中,<原始文件或目录路径>是要创建链接的文件或目录的路径,<链接文件路径>是要创建的软链接的路径。
    例如,假设当前目录下有一个文件file.txt,我们可以使用以下命令创建一个指向它的软链接:
    ln -s file.txt link.txt
    这样就创建了一个名为link.txt的软链接,它指向file.txt文件。

需要注意的是,软链接是一个指向原始文件或目录的引用,而不是实际的文件或目录本身。删除软链接不会影响原始文件或目录,但删除原始文件或目录可能会导致软链接失效。


指令ll -li

ll -li是一个Linux命令,用于显示文件或目录的详细信息,并以inode号进行排序。下面是该命令的一些说明:

  • ll是 “ls -l” 的简写,用于显示文件和目录的详细信息。
  • -li是两个选项的组合,其中 -l表示以长格式显示文件信息,包括文件权限、所有者、大小、修改日期等;而 -i表示显示文件的inode号。

通过执行 ll -li 命令,您将看到当前目录下所有文件和目录的详细信息,并按照inode号进行排序。


软链接

在这里插入图片描述结论:软链接本质上就是一个文件,有独立的inode


指令ln

在Linux系统中创建文件硬链接,可以通过ln命令来创建硬链接。ln命令的语法如下:

ln [选项] <源文件或目录> <目标文件或目录>

其中,源文件或目录是要创建链接的文件或目录的路径,目标文件或目录是要创建的链接的路径。

创建硬链接的命令格式为:

ln <源文件> <目标文件>

例如,要在当前目录下创建一个名为linkfile的硬链接,指向源文件sourcefile,可以使用以下命令:
ln sourcefile linkfile

注意,硬链接只能链接到同一个文件系统中的文件,且不能链接到目录。


硬链接

在这里插入图片描述

我们创建了硬链接之后可以发现。前面的文件信息发生了一个微小的变化,也就是文件权限后面的数字由1变成了2,而硬链接新出现的文件其初始数字就是2,这个数字从来没有讲述过

在这里插入图片描述

我们查看一下inode也可以发现,新出现的文件与旧文件inode竟然是一样的!

在这里插入图片描述
结论:硬链接本质不是一个独立的文件,因为它的inode编号和目标文件相同


1.2 软硬链接的原理

测试硬链接

  • 我们将硬链接的目标文件写入点数据
    在这里插入图片描述

可以看到我们修改目标文件的同时,硬链接生成的文件也会发生变化,其大小与目标文件同样是12,且修改时间相同,inode也没有改变

  • 我们删除目标文件
    在这里插入图片描述

可以看到,我们的硬链接产生的文件并没有什么变化,我们查看其文件数据可以清楚的看到,这个数据就是我们当初输入到目标文件的数据,这是什么情况?

其实也可以理解,其inode和目标文件是一摸一样的,也就是说他们对应的都是同一个文件,我们硬链接的工作特别像给目标文件进行一个重命名,并且源文件不改变。

硬链接的本质:一定没有新建文件,因为没有新的inode,只是新建了一个文件名,与目标文件inode相同的映射关系。


这个时候我们再看当初的这个2
在这里插入图片描述

其实这就是一个硬链接数,表明有多少个硬链接,表明了有多少个文件名与这一块数据有相同的映射关系,同时也叫引用计数

同时可以看到,硬链接就是建立了一个映射关系同时对引用计数++即可。

我们删掉文件后可以看到,引用计数从2变成了1
在这里插入图片描述


测试软链接

在这里插入图片描述
软链接创建的文件有独立的inode,有独立的inode那么就有独立的属性以及独立的数据内容。

软链接本质就是一个独立文件,软链接内容里面放的目标文件的路径!

软链接就相当于我们Windows里面的快捷方式,其存储的就是其可执行程序的路径

1.3 软硬链接的应用场景

1.3.1软链接

  • 我们创建一系列文件并输入内容给test.c

在这里插入图片描述

#include<stdio.h>
int main()
{
  printf("hello world\n");
  return 0;
}
  • 将文件编译,并把可执行文件移动到bin目录下

在这里插入图片描述

  • 我们想访问这个可执行文件就只能访问绝对路径访问

在这里插入图片描述

  • 我们还可以采用软链接的方式访问到这个可执行文件

在这里插入图片描述
我们就可以使用软链接的方式,在当前目录创建一个软链接的文件,这样就可以直接访问到深路径的文件,我们使用起来就更加方便


我们也可以采用硬链接的方式来达到访问深路径的文件
在这里插入图片描述

软链接使用起来还是更加方便一些,一般推荐软链接


系统有很多的软链接

ls -l /lib64/

在这里插入图片描述


1.3.2 硬链接

  • 我们创建一个普通文件以及一个目录
    在这里插入图片描述

可以发现普通文件的硬链接数是1,而目录一创建出来硬链接数就是2。

  • 我们进入empty目录下

在这里插入图片描述

我们可以看到empty目录下有隐藏的点文件,我们之前讲过,这个就是指的当前目录,它的inode与empty目录的inode是一模一样的,而它就是除了empty外另一个硬链接。

  • 我们进入empty目录下再创建一个a目录

在这里插入图片描述

这里可以看到我们的empty目录的硬链接数变成了3,这就是因为我们empty目录里的a目录里有一个自带的点点文件,这代表的是上级目录,它就是第三个empty目录的硬链接

由此得知:一个目录下有多少个子目录:硬链接数-2即可计算得到

注意:Linux中不允许给目录建立硬链接,但是可以建立软链接


2.动静态库

  • 静态库(.a):程序在编译链接的时候把库的代码链接到可执行文件中。程序运行的时候将不再需要静态库

  • 动态库(.so):程序在运行的时候才去链接动态库的代码,多个程序共享使用库的代码。

  • 一个与动态库链接的可执行文件仅仅包含它用到的函数入口地址的一个表,而不是外部函数所在目标文件的整个机器码

  • 在可执行文件开始运行以前,外部函数的机器码由操作系统从磁盘上的该动态库中复制到内存中,这个过程称为动态链接(dynamic linking)

  • 动态库可以在多个程序间共享,所以动态链接使得可执行文件更小,节省了磁盘空间。操作系统采用虚拟内存机制允许物理内存中的一份动态库被要用到该库的所有进程共用,节省了内存和磁盘空间。


我们是很经常使用库的,我们创建一个普通C文件,并编写简单代码

在这里插入图片描述

这里就是利用了C语言的库的,之前进行简单的讲解过,这是C语言的动态库

在这里插入图片描述


关于库我们有过一定的使用经验
库分为静态库以及动态库-----大部分的系统默认安装的是动态库,云服务器是静态库–(C标准库)默认是没有安装的
默认编译程序,用的是动态链接的,如果要静态要加-static

库的真实名字:lib. XXXX -a/so 去掉前缀以及后缀

2.1 动静态库的制作和使用

一般我们的程序执行会经历几个阶段

  1. a.h + a.c ---> a.o
  2. b.h + b.c ---> b.o
  3. c.h + c.c ---> c.o
  4. d.h + d.c ---> d.o
  5. 再结合libc.so/libc.a
  6. 最后main.c ------>main.o

库则是不提供.c文件

  1. a.h + a.o
  2. b.h + b.o
  3. c.h + c.o
  4. d.h + d.o

你只需要将main.c ------>main.o
注:这里的a、b、c、d只是概念文件

所谓的库就是将所有的.o文件用特定的方式,进行打包,形成一个文件

库的存在的意义:

  1. 提高开发效率
  2. 隐藏源代码

准备工作

在了解库的使用原理后我们来模拟实现一个

  1. 创建五个文件
    在这里插入图片描述
  2. 编写文件

add.c

#include "add.h"
int add(int a, int b)
{
  return a + b;
}

add.h

#ifndef __ADD_H__
#define __ADD_H__ 
int add(int a, int b); 
#endif // __ADD_H__

sub.h

#ifndef __SUB_H__
#define __SUB_H__ 
int sub(int a, int b); 
#endif // __SUB_H

sub.c

#include "add.h"
int sub(int a, int b)
{
  return a - b;
}

main.c

#include <stdio.h>
#include "add.h"
#include "sub.h"
 
int main()
{
  int a = 10;
  int b = 20;
  printf("add(%d, %d)=%d\n", a, b, add(a, b));
  a = 100;
  b = 20;
  printf("sub(%d,%d)=%d\n", a, b, sub(a, b));
}

生成.o文件
在这里插入图片描述

生成静态库

指令ar -rc

ar -rc是一个用于创建或更新静态库的命令。它是GNU工具链中的一个工具,用于将一组目标文件打包成一个静态库文件。下面是ar -rc命令的一些常见用法:

  • 创建静态库:可以使用ar -rc命令将多个目标文件打包成一个静态库文件。例如,要将文件1.o、文件2.o和文件3.o打包成一个名为libexample.a的静态库,可以执行以下命令:

ar -rc libexample.a 1.o 2.o 3.o

  • 更新静态库:如果已经存在一个静态库文件,可以使用ar -rc命令向其中添加新的目标文件或替换已有的目标文件。例如,要向名为libexample.a的静态库中添加一个新的目标文件file.o,可以执行以下命令:

ar -rc libexample.a file.o

  • 替换静态库中的目标文件:如果要替换静态库中已有的目标文件,可以使用ar -rc命令指定相同的目标文件名。例如,要替换名为libexample.a的静态库中的目标文件file.o,可以执行以下命令:

ar -rc libexample.a file.o

  • 查看静态库内容:可以使用ar -t命令来查看静态库中包含的目标文件列表。例如,要查看名为libexample.a的静态库中包含的目标文件列表,可以执行以下命令:

ar -t libexample.a


输入指令ar -rc libmymath.a add.o sub.o生成静态库
查看静态库中的目录列表 ar -tv libmymath.a
t:列出静态库中的文件
v:verbose 详细信息

在这里插入图片描述
所以库的本质就是把一堆.o打包形成一个文件,然后通过头文件来调用库。注意,库中不能包含main函数。

编译一下,即可运行

gcc (要形成的可执行文件名) main.c(所依赖的文件) -L .(-L + 路径表示myc这个库在哪个路径下)-lmymath(指明要链接mymath这个静态库)

在这里插入图片描述


生成动态库

fPIC:产生位置无关码,在将.c或者.cpp形成.o文件时,需要加上-fPIC。要形成动态库必须加上-fPIC。
在这里插入图片描述

形成动态库不需要用到其它指令,gcc编译器就可以形成动态库,只不过要加上-shared命令。

gcc -shared -o libmymath.so(名字,真正的库名要去掉lib和.so)sub.o add.o (所依赖的.o文件)

在这里插入图片描述
直接使用我们的这个动态库,那么就同样要告诉编译器我们库的名字和所在的路径(参考上面静态库路径的写法)。

在这里插入图片描述

2.2 将自己的库打包给别人

假设在我当前目录下有libmymath.so动态库,add.h,sub.h两个头文件,如果我想将这三个文件一起交给别人,就可以把它们打包一起放在一个目录下,一起压缩完再交给别人。
在这里插入图片描述

Makefile

 1 libmymath.so:add.o sub.o
  2     gcc -shared -o $@ $^
  3 .o:.c
  4     gcc -shared -c $<
  5 #add.o:add.c
  6 #   gcc -c -fPIC $< -o $@
  7 #sub.o:sub.c
  8 #   gcc -c -fPIC $< -o $@
  9 .PHONY:clean
 10 clean:
 11   rm -f *.o libmymath.so
 12 
 13 .PHONY:output                                                                                                                                                                           
 14 output:
 15         mkdir -p ./user/mylib/
 16         mkdir -p ./user/Headfile/
 17         cp -rf libmymath.so ./user/mylib/
 18         cp -rf add.h sub.h ./user/Headfile/
 19         tar -czf user.tgz user

在这里插入图片描述

user目录是通过user.tgz解压得到的,下面是user目录下的文件:

在这里插入图片描述

将两个头文件拷贝到usr/include目录下(编译器默认会到include目录下去寻找头文件),将库文件拷贝到usr/lib目录下,编译时指定库链接,就能够运行了。
在这里插入图片描述

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

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

相关文章

AskManyAI:一个GPT、Claude、Gemini、Kimi等顶级AI的决斗场

一直以来很多人问我能不能有个稳定&#xff0c;不折腾的全球AI大模型测试网站&#xff0c;既能够保证真实靠谱&#xff0c;又能够保证稳定、快速&#xff0c;不要老动不动就挂了、出错或者漫长的响应。 直到笔者遇到了AskManyAI&#xff0c;直接就惊艳住了&#xff01; 话不多…

公布应用程序

&#x1f4d5;作者简介&#xff1a; 过去日记&#xff0c;致力于Java、GoLang,Rust等多种编程语言&#xff0c;热爱技术&#xff0c;喜欢游戏的博主。 &#x1f4d8;相关专栏Rust初阶教程、go语言基础系列、spring教程等&#xff0c;大家有兴趣的可以看一看 &#x1f4d9;Jav…

亚马逊云科技官方重磅发布GenAI应用开发学习路线(全免费)

今天小李哥给大家分享的是亚马逊云科技&#xff08;AWS&#xff09;最近官方发布的GenAI应用开发最佳学习路线&#xff0c;不仅内容非常全面更主要的是全部免费&#xff01;大家动动小手就能成为GenAI开发大&#x1f42e;&#xff01; 1️⃣这个GenAI开发学习路线包括什么&…

.cur 鼠标光标编辑器

详解透明贴图和三元光栅操作 - CodeBus 鼠标指针文件格式解析——Windows&#xff08;二&#xff09; (qq.com) [C/C] RGBA数组生成Windows下的ico文件_c ico格式-CSDN博客 色环设计 - CodeBus 左键绘制 右键选颜色 ctrl右键设置鼠标热点 F1导出.cur文件 //代码来源&…

web3项目自动连接小狐狸以及小狐狸中的各种“地址”详解

刚做web3的时候&#xff0c;比较迷糊的就是人们口中说的各种地址&#xff0c;小狐狸钱包地址&#xff0c;私钥地址&#xff0c;跳转地址&#xff0c;接口地址&#xff0c;交易地址&#xff0c;等等XX地址&#xff0c;常常感觉跟做链的同事们说话不在一个频道。 这一小节&#x…

力扣:49. 字母异位词分组

知识点&#xff1a; 散列函数 散列函数能使对一个数据序列的访问过程更加迅速有效&#xff0c;通过散列函数&#xff0c;数据元素将被更快地定位&#xff1a; 1. 直接寻址法&#xff1a;取关键字或关键字的某个线性函数值为散列地址。即H&#xff08;key&#xff09;key或H&a…

CentOS 7安装Zookeeper

说明&#xff1a;本文介绍如何在CentOS 7操作系统下使用Zookeeper 下载安装 首先&#xff0c;去官网下载所需要安装的版本&#xff0c;我这里下载3.4.9版本&#xff1b; 上传到云服务器上&#xff0c;解压 tar -xvf zookeeper-3.4.9.tar.gz修改配置 进入Zookeeper目录下的co…

ssm049基于Vue.js的在线购物系统的设计与实现+vue

在线购物系统 摘 要 随着科学技术的飞速发展&#xff0c;各行各业都在努力与现代先进技术接轨&#xff0c;通过科技手段提高自身的优势&#xff1b;对于在线购物系统当然也不能排除在外&#xff0c;随着网络技术的不断成熟&#xff0c;带动了在线购物系统&#xff0c;它彻底改…

设计模式代码实战-外观模式

1、问题描述 小明家的电源总开关控制了家里的三个设备&#xff1a;空调、台灯和电视机。每个设备都有独立的开关密码&#xff0c;分别用数字1、2和3表示。即输入1时&#xff0c;空调关闭&#xff0c;输入2时&#xff0c;台灯关闭&#xff0c;输入3时&#xff0c;电视机关闭&am…

排序总结Java

文章目录 排序算法复杂度总结插入排序希尔排序归并排序快速排序堆排序 排序算法复杂度总结 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 插入排序 public class Sort {// 插入排序public int[] inserSort(int[] nums){for (int i 1; i < nums.length;…

科技助力输电线安全隐患预警,基于YOLOv8全系列【n/s/m/l/x】参数模型开发构建电力设备场景下输电线安全隐患目标检测预警系统

电力的普及让我们的生活变得更加便利&#xff0c;四通八达的电网连接着生活的方方面面&#xff0c;电力能源主要是依托于庞大复杂的电网电力设备进行传输的&#xff0c;有效地保障电网场景下输电线的安全对于保障我们日常生活所需要的电力有着重要的意义&#xff0c;但是电力设…

Redis报错:CROSSSLOT Keys in request don‘t hash to the same slot的解决方案

最近&#xff0c;项目上线的时候&#xff0c;出现了一个Redis的报错&#xff1a;CROSSSLOT Keys in request dont hash to the same slot&#xff0c;这个在内网环境下无法复现&#xff0c;因为正式环境的Redis是cluster集群模式&#xff0c;而我们内网环境是单机模式。(后面我…

Django第三方功能的使用

Django第三方功能的使用 Django REST framework前言1、Django--Restframework--coreapi版文档BUG:AssertionError: coreapi must be installed for schema support.How to run Django with Uvicorn webserver?2、序列化类 Serializer的使用模型序列化类 ModelSerializer的使用…

再写-全景拼接

全景拼接 1. 将读取进行灰度转化&#xff0c;并且输出图像&#xff0c;关键点和计算描述 import cv2 import numpy as np# 将读取进行灰度转化&#xff0c;并且输出图像&#xff0c;关键点和计算描述 image_left cv2.imread("C:\\Users\\HONOR\\Desktop\\image\\pinjie…

001_IoT/物联网通信协议基础: HTTP、Websocket、MQTT、AMQP、COAP、LWM2M一文搞懂

001_IoT/物联网通信协议基础: HTTP、Websocket、MQTT、AMQP、COAP、LWM2M一文搞懂 文章目录 001_IoT/物联网通信协议基础: HTTP、Websocket、MQTT、AMQP、COAP、LWM2M一文搞懂创作背景通信模型ISO/OSI七层模型 和 TCP/IP四层模型网络通信数据包格式&#xff08;Ethernet II&…

【微信小程序——案例——本地生活(列表页面)】

案例——本地生活&#xff08;列表页面&#xff09; 九宫格中实现导航跳转——以汽车服务为案例&#xff08;之后可以全部实现页面跳转——现在先实现一个&#xff09; 在app.json中添加新页面 修改之前的九宫格view改为navitage 效果图&#xff1a; 动态设置标题内容—…

【5G PHY】5G无线链路监测原理简述

博主未授权任何人或组织机构转载博主任何原创文章&#xff0c;感谢各位对原创的支持&#xff01; 博主链接 本人就职于国际知名终端厂商&#xff0c;负责modem芯片研发。 在5G早期负责终端数据业务层、核心网相关的开发工作&#xff0c;目前牵头6G算力网络技术标准研究。 博客…

车载电子电器架构 —— 平行开发策略

车载电子电器架构 —— 平行开发策略 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 屏蔽力是信息过载时代一个人的特殊竞争力,任何消耗你的人和事,多看一眼都是你的不对。非必要不费力证明自己…

架构师系列-搜索引擎ElasticSearch(八)- 集群管理故障恢复

故障转移 集群的master节点会监控集群中的节点状态&#xff0c;如果发现有节点宕机&#xff0c;会立即将宕机节点的分片数据迁移到其它节点&#xff0c;确保数据安全&#xff0c;这个叫做故障转移。 下图中node1是主节点&#xff0c;其他两个节点是从节点 节点故障 此时node1…

【LeetCode】回溯算法类题目详解

所有题目均来自于LeetCode&#xff0c;刷题代码使用的Python3版本 回溯算法 回溯算法是一种搜索的方法&#xff0c;在二叉树总结当中&#xff0c;经常使用到递归去解决相关的问题&#xff0c;在二叉树的所有路径问题中&#xff0c;我们就使用到了回溯算法来找到所有的路径。 …