【Linux】软硬链接和动静态库
文章目录
- 1. 软硬链接
- 💥硬链接(Hard Link)
- 💥软链接(Symbolic Link)
- 2. 动静态库
- 💥静态库(Static Libraries)
- 💥动态库(Dynamic Libraries)
1. 软硬链接
在Linux系统中,文件链接分为两种类型:硬链接(Hard Link)和软链接(也称为符号链接或Symbolic Link)。它们都是用于创建文件的额外入口点,但是工作原理和使用场景有所不同。
💥硬链接(Hard Link)
- 定义:硬链接是一个指向原始文件的直接链接。硬链接是一个与原始文件共享inode的文件,它们在文件系统中实际上是同一个文件。
每个文件在Linux系统中都有一个inode,它包含了文件的所有元数据信息,如权限、所有者等,但不包含文件名。当创建一个硬链接时,实际上是为同一个inode创建了一个新的文件名,这意味着两个或多个硬链接实际上指向的是同一个文件数据。
- 特性:
- 硬链接不能跨文件系统。
- 不能对目录创建硬链接(除了
ln命令的特殊选项外,这通常是为了安全考虑)。 - 对一个文件的修改会反映在所有的硬链接上
- 如果原始文件被删除,只要还有一个硬链接存在,文件的数据就不会被删除。
删除原始文件后,硬链接仍然可以访问原始文件的内容,这是因为Linux系统在创建硬链接时,会使用引用计数的方式,记录一个文件共有多少个硬链接,当删除一个文件时,只有将其所有的硬链接都删除,这个文件才算真正的删除,否则都可以通过任意一个硬链接访问文件内容。
- 创建方法:使用
ln命令。例如,要为文件file.txt创建一个名为file-hard.link的硬链接,可以执行命令ln file.txt file-hard.link。(注意文件的后缀可以随意选择)

最开始创建file.txt文件,只有它自己,所以引用计数为1,后来为它新建了一个硬链接file-hard.link,引用计数就变为2,因为它们两个本质上是同一个文件,所以file-hard.link的引用计数也为2,与file.txt保持一致。
关于引用计数:
新建一个目录文件,它一开始的硬链接引用计数就是2,除了它自己以外,它里面还包含一个隐藏文件.,这个其实也是该目录的硬链接,如下图所示:

而上图中的
..文件则是指向上一级目录的硬链接,每个目录在创建的时候都会自动创建这两个文件。
💥软链接(Symbolic Link)
- 定义:软链接是一个指向原始文件或目录的特殊文件,它包含了另一个文件或目录的路径名。通过访问软链接,可以间接访问源文件。
这意味着软链接形成的文件是不同于原始文件的,它们有着不同的inode编号,与硬链接不同
-
特性:
- 软链接可以跨文件系统。
- 可以对文件或目录创建软链接。
- 如果原始文件或目录被移动或删除,软链接将失效(变为“断开”状态)。
- 原始文件的权限信息、时间戳等软链接都是不保留的,它仅仅保存了原始文件的路径名。
-
创建方法:使用
ln -s命令。例如,要为文件sfile.txt创建一个名为sfile-soft.link的软链接,可以执行命令ln -s sfile.txt sfile-soft.link。

使用场景:
- 硬链接适合于需要确保文件不会因为原文件的删除而丢失的情况,尤其是在同一文件系统内。减少磁盘空间占用以及创建备份文件等场景。
- 软链接则更灵活,适用于需要跨文件系统链接或者链接到可能经常变动的位置的情况。此外,软链接可以更容易地识别和管理,因为它们本质上是文本形式的路径。
总结起来,软连接有独立的inode,软连接内容上保存的是目标文件的路径,当原始文件删除后,软链接将会失效;例如windows的快捷方式。而硬链接不是独立的文件,没有独立的inode,本质是一组文件名与目标文件的映射关系(别名),删除原始文件后,因为引用计数的存在,本质目标文件并没被删除,硬链接仍然可以访问原始文件的内容。
2. 动静态库
在Linux系统中,库文件分为静态库(Static Libraries)和动态库(Dynamic Libraries)。这两种类型的库各有优缺点,适用于不同的场景。
💥静态库(Static Libraries)
定义:
- 静态库是在编译阶段就被链接到目标代码中的库。这意味着当一个程序被编译时,它会包含它所依赖的静态库的副本。
优点:
- 程序运行时不需要外部库文件,因为所有需要的代码都已经被整合进可执行文件中。
- 可以确保程序总是使用特定版本的库,避免了所谓的“DLL地狱”问题(在Windows环境中常见,指的是由于不同应用程序可能依赖于不同版本的同一个库而导致的问题)。
缺点:
- 每个使用该库的程序都会有一个库的副本,这会导致磁盘空间的浪费。
- 如果静态库需要更新,那么所有使用这个库的应用程序都需要重新编译和链接。
创建静态库
- 编写源代码并将其编译为目标文件(.o):
gcc -c mystdio.c -o mystdio.o - 创建静态库文件可以使用
ar命令:ar rc libmystdio.a mystdio.o
libmystdio.a是静态库文件的名称mystdio.o是要打包进库文件的目标文件rc表示replace create
静态库通常具有
.a扩展名。
使用静态库
方法一:使用带路径的库进行链接
gcc myprogram.c -I/path/to/include -L/path/to/library -lmylib -o myprogram
-
-I/path/to/include指定头文件所在的路径 -
-L/path/to/library指定库文件所在的路径 -
-lmylib指定要链接的库文件的名称(省略了前缀lib和文件扩展名.a) -
使用静态库进行链接时,可以使用
-l和-L选项指定库文件的位置和名称,-l指定库的名字
gcc在查动静态库时不会在当前目录下查,所以我们需要指定路径
方法二:将库安装到系统中直接使用
- 首先,编译源代码生成静态库文件(通常以
.a为文件扩展名)。可以使用gcc或g++命令进行编译。例如,编译一个名为libexample.a的静态库文件可以使用以下命令:
gcc -c example.c # 编译源代码生成目标文件
ar rc libexample.a example.o # 使用ar工具将目标文件打包成静态库
- 将生成的静态库文件复制到系统目录中,例如
/lib64/。可以使用cp命令进行复制,例如:
sudo cp libexample.a /lib64/ # 将静态库文件复制到系统目录
sudo cp libexample.h /usr/include/ #将静态库头文件复制到系统目录
- 更新库缓存。在某些Linux发行版中,需要手动更新库缓存以使系统可以找到新安装的库。可以使用以下命令更新库缓存:
sudo ldconfig # 更新库缓存
- 确认安装成功。可以使用
ls命令检查静态库文件是否已经复制到系统目录中,例如:
ls /lib64/libexample.a # 检查静态库文件
- 在编译和链接其他程序时,可以使用
-l选项指定使用安装的静态库。例如,使用gcc命令编译一个名为example_program.c的程序,并链接使用静态库libexample.a可以使用以下命令:
gcc example_program.c -o example_program -lexample
链接库时需要省去前缀lib和后缀.a,动态库也是一样,直接 -lexample即可
这样,就可以将静态库安装到系统中,并且可以直接在其他程序中使用该库。
💥动态库(Dynamic Libraries)
定义:
- 动态库(也称为共享库)是在程序运行时被加载的。这意味着多个程序可以共享同一份库文件,从而节省内存和磁盘空间。
优点:
- 节省磁盘空间和内存,因为多个程序可以共享同一个库文件。
- 库更新时不需要重新编译或重新链接应用程序,只需替换库文件即可(前提是API没有改变)。
缺点:
- 程序运行时需要有相应的动态库存在,否则可能会导致程序无法启动。
创建动态库
- 动态库通常具有
.so(shared object) 扩展名。 - 创建动态库可以使用
gcc编译器的-fPIC和-shared选项。
例如,编译一个名为libexample.so的动态库文件可以使用以下命令:
gcc -fPIC -c example.c #编译.o文件
gcc -shared -o libexample.so example.o # 编译源代码生成动态库
-fPIC:形成与位置无关码
使用动态库
方法一:使用带路径的库进行链接
这里与静态库一致
gcc myprogram.c -I/path/to/include -L/path/to/library -lmylib -o myprogram
-
-I/path/to/include指定头文件所在的路径 -
-L/path/to/library指定库文件所在的路径 -
-lmylib指定要链接的库文件的名称(省略了前缀lib和文件扩展名.a) -
使用动态库进行链接时,可以使用
-l和-L选项指定库文件的位置和名称,-l指定库的名字 -
可以使用
ldd命令查看一个程序所依赖的动态库列表,例如:ldd myprogram。
gcc在查动静态库时不会在当前目录下查,所以我们需要指定路径
注意链接动态库形成可执行程序后,运行可执行文件时,系统是需要找到动态库的位置,也就是运行可执行程序时,动态库是需要加载的,所以如何让系统找到动态库?
- 将动态库文件复制到系统目录中,系统会默认在该目录下寻找
- 在系统路径建立动态库文件的软链接
- Linux系统中除了会在系统路径下寻找动态库,还会在环境变量中寻找,该环境变量为
LD_LIBRARY_PATH - ldconfig 配置/etc/ld.so.conf.d/,ldconfig更新
方法二:将库安装到系统中直接使用
- 将生成的动态库文件复制到系统目录中,例如
/lib64。可以使用cp命令进行复制,例如:
sudo cp libexample.so /lib64/ # 将动态库文件复制到系统目录
sudo cp libexample.h /usr/include/ #将静态库头文件复制到系统目录
- 更新库缓存。在某些Linux发行版中,需要手动更新库缓存以使系统可以找到新安装的库。可以使用以下命令更新库缓存:
sudo ldconfig # 更新库缓存
- 确认安装成功。可以使用
ls命令检查动态库文件是否已经复制到系统目录中,例如:
ls /lib64/libexample.so # 检查动态库文件
- 在编译和运行其他程序时,可以使用
-l选项指定使用安装的动态库。例如,使用gcc命令编译一个名为example_program.c的程序,并链接使用动态库libexample.so可以使用以下命令:
gcc example_program.c -o example_program -lexample
这样,就可以将动态库安装到系统中,并且可以直接在其他程序中使用该库。此外,编译形成可执行程序后,如果删除了需要的动态库,程序也是不可以运行的。
原理上理解动态库:

进程在链接动态库时,操作系统会先将动态库加载到内存中,然后将动态库在内存中的地址通过页表映射到进程地址空间的共享区,这样进程在执行库方法的时候就是在自己的地址空间中跳转运行的。当另一个程序也要使用同一个动态库时就不需要再重复加载该动态库到内存里了,只需要通过进程的页表进行映射之前加载到内存的动态库即可,多个程序也是这样。
总结
如果同时提供动态库与静态库,gcc/g++默认使用动态库;如果要使用静态库必须使用静态链接-static来指明;如果使用动态链接但是只有静态库,那么gcc/g++只能选择静态库进行链接。
选择使用静态库还是动态库取决于具体的需求。如果关注程序的独立性和稳定性,且不介意较大的程序大小,可以选择静态库;如果更关心资源的有效利用,并且可以保证目标系统上有适当的动态库版本,那么使用动态库是更好的选择。
相关文章:
【Linux】软硬链接和动静态库
🔥 个人主页:大耳朵土土垚 🔥 所属专栏:Linux系统编程 这里将会不定期更新有关Linux的内容,欢迎大家点赞,收藏,评论🥳🥳🎉🎉🎉 文章目…...
HarmonyOS入门 : 获取网络数据,并渲染到界面上
1. 环境搭建 开发HarmonyOS需要安装DevEco Studio,下载地址 : https://developer.huawei.com/consumer/cn/deveco-studio/ 2. 如何入门 入门HarmonyOS我们可以从一个实际的小例子入手,比如获取网络数据,并将其渲染到界面上。 本文就是基于…...
【贪心】【哈希】个人练习-Leetcode-1296. Divide Array in Sets of K Consecutive Numbers
题目链接:https://leetcode.cn/problems/divide-array-in-sets-of-k-consecutive-numbers/description/ 题目大意:给出一个数组nums[]和一个数k,求nums[]能否被分成若干个k个元素的连续的子列。 思路:比较简单,贪心就…...
【数据库实验一】数据库及数据库中表的建立实验
目录 实验1 学习RDBMS的使用和创建数据库 一、 实验目的 二、实验内容 三、实验环境 四、实验前准备 五、实验步骤 六、实验结果 七、评价分析及心得体会 实验2 定义表和数据库完整性 一、 实验目的 二、实验内容 三、实验环境 四、实验前准备 五、实验步骤 六…...
Web服务nginx基本实验
安装软件: 启动服务: 查看Nginx服务器的网络连接信息,监听的端口: 查看默认目录: 用Windows访问服务端192.168.234.111的nginx服务:(防火墙没有放行nginx服务,访问不了) …...
Ubuntu实现双击图标运行自己的应用软件
我们知道在Ubuntu上编写程序,最后编译得到的是一个可执行文件,大致如下 然后要运行的时候在终端里输入./hello即可 但是这样的话感觉很丑很不方便,下边描述一种可以类似Windows上那种双击运行的实现方式。 我们知道Ubuntu是有一些自带的程序…...
js id字符串转数组
将一个逗号分隔的字符串(例如 "12,123,213,")转换为一个 JavaScript 数组,并去除多余的逗号,可以使用以下几种方法。这里我将展示几种常见的方式: 方法 1: 使用 split 和 filter 你可以使用 split 方法将字…...
《手写Spring渐进式源码实践》实践笔记(第十八章 JDBC功能整合)
文章目录 第十八章 JDBC功能整合背景技术背景JDBC JdbcTemplate关键特性 用法示例业务背景 目标设计实现代码结构类图实现步骤 测试事先准备属性配置文件测试用例测试结果: 总结 第十八章 JDBC功能整合 背景 技术背景 JDBC JDBC(Java Database Conne…...
边缘计算在智能交通系统中的应用
💓 博客主页:瑕疵的CSDN主页 📝 Gitee主页:瑕疵的gitee主页 ⏩ 文章专栏:《热点资讯》 边缘计算在智能交通系统中的应用 边缘计算在智能交通系统中的应用 边缘计算在智能交通系统中的应用 引言 边缘计算概述 定义与原…...
HTML5+css3(浮动,浮动的相关属性,float,解决浮动的塌陷问题,clear,overflow,给父亲盒子加高度,伪元素)
浮动的相关属性 以下使浮动的常用属性值: float: 设置浮动 以下属性: left : 设置左浮动 right : 设置右浮动 none :不浮动,默认值clear 清除浮动 清除前面兄弟元素浮动元素的响应 以下属性: left &…...
【C++ 滑动窗口】2134. 最少交换次数来组合所有的 1 II
本文涉及的基础知识点 C算法:滑动窗口及双指针总结 LeetCode2134. 最少交换次数来组合所有的 1 II 交换 定义为选中一个数组中的两个 互不相同 的位置并交换二者的值。 环形 数组是一个数组,可以认为 第一个 元素和 最后一个 元素 相邻 。 给你一个 二…...
使用 PyTorch 实现并测试 AlexNet 模型,并使用 TensorRT 进行推理加速
本篇文章详细介绍了如何使用 PyTorch 实现经典卷积神经网络 AlexNet,并利用 Fashion-MNIST 数据集进行训练与测试。在训练完成后,通过 TensorRT 进行推理加速,以提升模型的推理效率。 本文全部代码链接:全部代码下载 环境配置 为了保证代码在 GPU 环境下顺利运行,我们将…...
Python 数据可视化详解教程
Python 数据可视化详解教程 数据可视化是数据分析中不可或缺的一部分,它通过图形化的方式展示数据,帮助我们更直观地理解和分析数据。Python 作为一种强大的编程语言,拥有丰富的数据可视化库,如 Matplotlib、Seaborn、Plotly 和 …...
springboot集成opencv开源计算机视觉库
最近项目需要用到opencv,网上看到很多资料都是下载安装并且引入jar包与dll文件,感觉很麻烦,不是我想要的,于是花时间折腾了下,不需要任何安装与引入jar包与dll文件,简单方便,快速上手。 先说说…...
CCF ChinaOSC |「开源科学计算与系统建模openSCS专题分论坛」11月9日与您相约深圳
2024年11月9日至10日,以“湾区聚力 开源启智”为主题的2024年中国计算机学会中国开源大会(CCF ChinaOSC)将在深圳召开。大会将汇聚国内外学术界、顶尖科技企业、科研机构及开源社区的精英力量,共同探索人工智能技术和人类智慧的无…...
2024年11月8日上海帆软用户大会
2024年11月8日上海帆软用户大会 2024年11月8日,上海成功举办了帆软用户大会,主题为“数字聚力,绽放新机”。大会汇聚了众多行业专家和企业代表,共同探讨数字化转型和商业智能领域的最新趋势和实践。 大会亮点: 专家…...
信息泄露漏洞一文速通
文章目录 信息泄露漏洞一文速通敏感信息の概念敏感信息の分类企业敏感信息用户敏感信息站点敏感信息 如何挖掘信息泄露漏洞?信息泄露风险清单(checklist)未授权访问类文件与数据泄露开发与调试信息泄露公共配置文件泄露其他敏感信息泄露点 威…...
Android 启动时应用的安装解析过程《二》
上一篇内容说到InitAppsHelper这个类的initSystemApps函数,只说了一下几个重要参数的来源还没展开,这里继续,有兴趣的可以看链接: Android 启动时应用的安装解析过程《一》 一、系统应用的扫描安装 /*** Install apps from system dirs.*/Gu…...
智谱AI:ChatGLM强大的生成式语言模型
目录 智谱AI:ChatGLM强大的生成式语言模型 一、ChatGLM的定义与特点 二、ChatGLM的应用场景 三、举例说明 四、注意事项 智谱AI:ChatGLM强大的生成式语言模型 它通过对话的方式能够生成自然流畅的文本,这一特性使其在多个领域都有广泛的应用潜力,特别是在智能对话和智能…...
git tag
已经发布了 v1.0 v2.0 v3.0 三个版本,这个时候,我突然想不改现有代码的前提下,在 v2.0 的基础上加个新功能,作为 v4.0 发布。就可以检出 v2.0 的代码作为一个 branch ,然后作为开发分支。 要查看仓库中的所有标签 gi…...
Xshell远程连接Kali(默认 | 私钥)Note版
前言:xshell远程连接,私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...
循环冗余码校验CRC码 算法步骤+详细实例计算
通信过程:(白话解释) 我们将原始待发送的消息称为 M M M,依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)(意思就是 G ( x ) G(x) G(x) 是已知的)࿰…...
mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包
文章目录 现象:mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时,可能是因为以下几个原因:1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...
Map相关知识
数据结构 二叉树 二叉树,顾名思义,每个节点最多有两个“叉”,也就是两个子节点,分别是左子 节点和右子节点。不过,二叉树并不要求每个节点都有两个子节点,有的节点只 有左子节点,有的节点只有…...
初学 pytest 记录
安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...
初探Service服务发现机制
1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能:服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源…...
Caliper 负载(Workload)详细解析
Caliper 负载(Workload)详细解析 负载(Workload)是 Caliper 性能测试的核心部分,它定义了测试期间要执行的具体合约调用行为和交易模式。下面我将全面深入地讲解负载的各个方面。 一、负载模块基本结构 一个典型的负载模块(如 workload.js)包含以下基本结构: use strict;/…...
LangFlow技术架构分析
🔧 LangFlow 的可视化技术栈 前端节点编辑器 底层框架:基于 (一个现代化的 React 节点绘图库) 功能: 拖拽式构建 LangGraph 状态机 实时连线定义节点依赖关系 可视化调试循环和分支逻辑 与 LangGraph 的深…...
LCTF液晶可调谐滤波器在多光谱相机捕捉无人机目标检测中的作用
中达瑞和自2005年成立以来,一直在光谱成像领域深度钻研和发展,始终致力于研发高性能、高可靠性的光谱成像相机,为科研院校提供更优的产品和服务。在《低空背景下无人机目标的光谱特征研究及目标检测应用》这篇论文中提到中达瑞和 LCTF 作为多…...
webpack面试题
面试题:webpack介绍和简单使用 一、webpack(模块化打包工具)1. webpack是把项目当作一个整体,通过给定的一个主文件,webpack将从这个主文件开始找到你项目当中的所有依赖文件,使用loaders来处理它们&#x…...
