前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >硬链接与符号链接

硬链接与符号链接

作者头像
书唐瑞
发布2022-06-02 15:04:14
2.2K0
发布2022-06-02 15:04:14
举报
文章被收录于专栏:Netty历险记Netty历险记

【环境】

虚拟机VirtualBox

Ubuntu20虚拟机上有2块硬盘

一个30G大小, 一个10G大小

【分区,格式化,挂载】

启动Ubuntu20虚拟机后, 使用 fdisk -l 查看磁盘信息

接下来对10G的硬盘进行分区,格式化,挂载.

fdisk /dev/sdb

【1】输入n 表示添加一个新的分区

【2】输入p表示分区类型是主分区

【3】输入1表示这个主分区是磁盘的第一个分区

【4】default 2048表示这个主分区的起始扇区是2048

【5】+5120M 表示这个主分区大小是5120M = 5G, 我们把这个10G的磁盘先拿出来5G作为第一个主分区

【6】输入w表示分区信息持久化

再次使用fdisk -l查看磁盘信息,就可以看到刚才的分区了

分区完成之后, 紧接着就是对这个新的/dev/sdb1分区进行格式化.

mkfs -t ext3 -c /dev/sdb1

格式化完成之后, 紧接着就是挂载, 将这个分区挂载到某个目录下, 我们挂载到/mnt目录下

使用df -TH 查看

信息都是正确的

但是,一旦重启机器, 挂载信息就不存在了, 因此还需要修改一下/etc/fstab文件, 新增一条关系记录

环境搭建完成

【创建硬链接和符号链接】

给read_disk.py文件创建硬链接和符号链接.

ln read_disk.py sl_read_disk.py

硬链接

ln -s read_disk.py sl_read_disk.py

软链接

同时查看下这3个文件的inode值

最左侧表示每个文件的inode值, 可以看出来, 硬链接文件与原文件的inode值相同, 软链接文件生成了新的inode值.

使用stat命令分别查看三个文件信息

可以看到原文件和硬链接文件的信息是一样的, 而软链接的信息就是不同的.

而且软链接的内容大小是12, 这12个字符是什么信息呢? 也就是说软链接sl_read_disk.py文件里面存储的是什么?

我们可以数一下软链接指向的原文件名称的字符数,正好是12字符, 难道是巧合?

而且我们还发现一个问题

软链接占用的磁盘空间居然是0, 明明实际大小是12, 怎么会不占用磁盘块呢? 不敢相信. 其实这是操作系统的优化, 因为这个软链接只有12个字符大小, 操作系统虽然默认会给每个文件至少分配4K大小的空间, 但如果给这个软链接分配4K大小空间, 几乎是浪费了4K的空间, 因此当文件很小的时候, 文件的实际内容是与元信息存储在一起的.

文件的信息分为元信息和实际数据两个部分, 我们使用stat看到的都是元信息

假如我们创建一个文件名称大于60个字符的文件, 然后给它创建一个软链接那么就会看到软链接占用了磁盘块.

我用的Ubuntu20只有文件名称大于等于60个字符, 软链接文件才会占用磁盘块

创建012345678901234567890123456789012345678901234567890123456789.c文件,并给它创建了一个软链接文件 number_sl.c 查看软链接文件元信息, 显示占用了8个磁盘块

每个磁盘块默认512字节

这个number_sl.c软链接文件大小是62字节, 我们就看下这个62字节是什么内容.

首先查看下number_sl.c所在的挂载点

stat --format=%m number_sl.c

查看挂载点所在的分区

dubug指定的/dev/sda5分区

debugfs /dev/sda5

如上图, 软链接number_sl.c文件中存储的就是原文件的名称, 也就是使用ln -s 012345678901234567890123456789012345678901234567890123456789.c number_sl.c 命令创建软链接的原文件名称.

总结: 软链接占用实际的磁盘块空间, 软链接中存储的是原文件名称

接下来我们把软链接都删除, 只保留原文件和硬链接, 以及再新增一个1.txt文件

通过ll 命令查看文件大小共计20K. 然而你现在看到的都不是真实的.

首先1.txt文件内容我只写了4个字符, 所以它实际大小4个字节, 但是霸占了4K的磁盘空间, 因为操作系统默认会给每个文件至少分配4K大小空间. read_disk.py是原文件, 也会霸占4K的磁盘空间. 而硬链接指向的是原文件, 硬链接并没有占有实际的磁盘空间, 但是ll命令在统计大小的时候, 不会在意这些的, 虽然原文件和硬链接都执向同一个文件, 实际只占有4K磁盘空间, 但是ll命令依然按照4K+4K来统计大小.

我们使用du -h 命令统计的才是实际占有磁盘块大小空间

实际上只有当前目录占有4K, 1.txt文件占有4K, 原文件read_disk.py占有4K的磁盘块空间, 所以实际是12K,并非ll命令统计的20K. 毕竟这两个命令站在的角度不同, 看待`问题`的结果也不同.

总结: 硬链接不会占用磁盘块, 它指向原文件

再来看一个情况, 如下图

文件大小40984个字节, 文件占用磁盘大小16*512=8192个字节. 文件的实际大小居然比装它的所有磁盘块的和还大, 这是本文中第二种遇到的size > 磁盘块的情况了. 而这里说的这种情况是因为这个3.txt文件是个空洞文件, 也就是说文件头尾有数据, 中间大片空间都是没有数据的.

使用命令od -c 3.txt 查看文件内容, 文件头部有www.infuq.com信息, 尾部有个字符v, 文件中间没有任何数据.

网上之前看过一篇文章, 大概就是说某个文件大约几个G大小, 可以删除那个文件一下子就删除了. 根本原因就在于那个文件是个空洞文件. 使用ll命令看文件大小貌似很大, 但是ll命令欺骗了我们, 实际文件大小很小, 使用du命令看到的大小才是真实的.

之前还在网上看过一篇文章说, 一个数据库文件几百G, 怎么可以很快把它删除掉. 也是运用了硬链接的原理,给文件创建一个硬链接, 然后就可以把原文件删除了. 其实删除原文件也只是把原文件的元信息删除掉,实际的数据块并没有被删除, 因为硬链接还指向着数据块, 这也是运用硬链接解决删除大文件的原理.

在文章一开始我们新增了一个分区, 现在就可以派上用场了. 上面的实验说明都是在同一个目录下创建软链接和硬链接, 也就是说它们都属于同一个磁盘同一个分区.

现在, 原文件还是这个原文件read_disk.py 接下来我要在新的/mnt挂载点对应的/dev/sdb1分区创建硬链接和软链接.

创建硬链接失败

创建软链接成功

总结: 软链接可以跨分区创建, 硬链接不可以跨分区创建

即便两个分区是相同的文件系统也不可以跨分区创建硬链接, 是机制不允许, 并不是文件系统的区别.

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-03-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Netty历险记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档