inode定义

inode是linux系统中用作数据索引的标识符。简单来说,inode指示了一个文件的基本信息,如inode编号、修改时间、文件的位置等。

如同一本书的目录,会直接告诉你想看的章节是在第几页。不同的是,书是以页为单位的,而Linux文件存取是以“块”为单位的。

<!--more-->

找寻文件

操作系统在读取硬盘的时候,会一次性读取一个“块”(一个“块”的大小往往是4KB,包含了连续8个扇区,每个扇区存储512个字节)。而inode就告诉了文件位于哪个“块”,于是系统就会从这个“块”开始读取内容,我们就可以看到文件的内容。

每个文件都有对应的inode,存储着这个文件的基本信息。Linux系统不使用文件名,而使用inode号来识别文件。对于使用者,我们是通过文件名寻找、打开文件;对于系统,是通过以下三步找到的:

  1. 系统找到这个文件名对应的inode号
  2. 通过inode号,获取inode信息
  3. 根据inode信息,找到文件数据所在的block,读取内容

inode内容

inode 包含了文件的以下基本信息:

  • 文件的字节数
  • node 编号
  • 文件拥有者的 Uid
  • 文件所属group的 Gid
  • 文件的读、写、执行权限
  • 文件的时间戳,共有三个:
    • change:inode 上一次变动的时间
    • modify:文件内容上一次变动的时间
    • access:文件上一次打开的时间
  • 链接数,即有多少文件名指向这个inode
  • 文件数据 block 的位置

我们可以使用 stat 命令查看文件的inode信息,如:

$ stat v0.1.0.zip File: ‘v0.1.0.zip’Size: 94267       Blocks: 192        IO Block: 4096   regular file
Device: 811h/2065d  Inode: 5659765     Links: 1
Access: (0640/-rw-r-----)  Uid: ( 3457/mart_bda)   Gid: ( 3457/mart_bda)
Access: 2018-06-12 14:22:18.434027485 +0800
Modify: 2018-06-12 14:18:00.840994081 +0800
Change: 2018-06-12 14:18:00.840994081 +0800Birth: -

也可以在 ls 后加上 -i 直接获取inode编号:

$ ls -i v0.1.0.zip
5659765 v0.1.0.zip

inode大小

inode存储了文件的基本信息,虽然信息很少,但是也会占用空间。
硬盘格式化的时候,操作系统自动将硬盘分为两个区域:

  • 数据区:存放文件内容
  • inode 区:存放 inode 包含的信息,也叫作 inode table

每个 inode 节点的大小,一般是 128 字节或 256 字节。inode节点的总数,在硬盘格式化时就固定了。一般,数据区每1KB或2KB,inode区就会增加一个 inode。

假如在一块 1GB 的硬盘中,每个 inode 节点的大小为 128 字节,那么 inode 表的大小就会达到 128 MB,占整块硬盘的 12.8%。既然 inode 节点总数是有限的,那么分区的节点数就有用完的时候,一旦 inode 用完,即使磁盘空间还有剩余,也不能再存放任何数据,因为需要保证每个文件必须有一个 inode。

查看每个硬盘分区的 inode 或者磁盘容量的使用情况,可以使用 df 命令加上参数 -i 或者 -h,如:

文件-h, --human-readable 使用人类可读的格式(预设值是不加这个选项的...)

文件-H, --si 很像 -h, 但是用 1000 为单位而不是用 1024

文件-i, --inodes 列出 inode 资讯,不列出已使用 block

$ df -i
Filesystem        Inodes   IUsed     IFree IUse% Mounted on
/dev/sda5      275436544  801853 274634691    1% /
devtmpfs         8192960     524   8192436    1% /dev
tmpfs            8195307       4   8195303    1% /dev/shm
tmpfs            8195307     765   8194542    1% /run
tmpfs            8195307      13   8195294    1% /sys/fs/cgroup
/dev/sda2         204800     342    204458    1% /boot
/dev/sdb1       11443200 3329257   8113943   30% /data0
tmpfs            8195307       1   8195306    1% /run/user/0
tmpfs            8195307       1   8195306    1% /run/user/3457
$ df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda5       263G  134G  130G  51% /
devtmpfs         32G     0   32G   0% /dev
tmpfs            32G   12K   32G   1% /dev/shm
tmpfs            32G  394M   31G   2% /run
tmpfs            32G     0   32G   0% /sys/fs/cgroup
/dev/sda2       197M  139M   58M  71% /boot
/dev/sdb1        11T  5.2T  5.2T  51% /data0
tmpfs           6.3G     0  6.3G   0% /run/user/0
tmpfs           6.3G     0  6.3G   0% /run/user/3457

关于 df -h -i 的区别,可以参考 Linux df命令。

文件操作对 inode 的影响

要理解文件的操作对 inode 的影响,先要理解目录的原理。目录对外表现是一个容器,存放着子文件和子目录,实际上在系统内部,目录本身也是一个文件,目录文件的内容即是该目录下的文件名与 inode 号的映射表(即一个个的目录项)。

因此,linux访问一个文件时,要先查询到上一级目录,根据目录内容查找到文件对应的 inode号,然后读取对应的 block。

cp 命令

系统内部会执行以下操作:

  1. 分配一个未被使用的 inode 号,在 inode 表中新添一个项目。如果是覆盖复制,则 inode号不变,沿用之前同名文件的 inode 号。

  2. 在目录中新建一个目录项,并指向步骤 1 中的 inode。

  3. 把数据复制到 block 中。

rm 命令

系统内部会执行以下操作:

  1. 减少待删除文件名所对应的 inode 的链接数量,如果链接数变为0,则释放 inode,同时数据块放到可用空间中(对外表现为数据已删除,因为随时可以覆盖。如果没有覆盖,数据还可以恢复;一旦覆盖了,那么删除的数据无法恢复。)。

  2. 删除目录中的目录项。

mv 命令

如果目标文件和源文件属于同一个文件系统:

  1. 在目标文件的目录中新建目录项
  2. 删除源文件的目录中的目录项
  3. 目标文件名会指向源文件名的 inode。因此该操作对 inode 没有影响(除了时间戳),对数据的位置也没有影响,不移动任何数据。

如果目标文件和源文件属于不同文件系统:

  1. 相当于 cp + rm。

ln 命令

硬链接

一般情况下,文件名和 inode 号是一一对应,但是也有可能多个文件名指向同一个inode号,即硬链接。

  • 硬链接可以实现用不同的文件名访问同一个文件;
  • 对文件内容修改,会影响到所有的文件名;
  • 但是,删除一个文件名,不影响其他文件名的访问。

举个栗子

创建硬链接的命令:

ln [source file] [new file]

如:

$ ll -h -i
total 479M
5659849 -rw-r----- 1 mart_bda mart_bda 479M Jun 13 10:57 test_file
$ ln test_file test_file_hardlink
$ ll -i -h
total 957M
5659849 -rw-r----- 2 mart_bda mart_bda 479M Jun 13 10:57 test_file
5659849 -rw-r----- 2 mart_bda mart_bda 479M Jun 13 10:57 test_file_hardlink

这样,两个文件的 inode 号均为 5659849。

具体查看两个文件的 inode 内容:

$ stat test_fileFile: ‘test_file’Size: 501577774   Blocks: 979656     IO Block: 4096   regular file
Device: 811h/2065d  Inode: 5659849     Links: 2
Access: (0640/-rw-r-----)  Uid: ( 3457/mart_bda)   Gid: ( 3457/mart_bda)
Access: 2018-06-13 10:57:13.961409755 +0800
Modify: 2018-06-13 10:57:14.931383436 +0800
Change: 2018-06-13 10:58:11.382851699 +0800Birth: -
$ stat test_file_hardlink File: ‘test_file_hardlink’Size: 501577774   Blocks: 979656     IO Block: 4096   regular file
Device: 811h/2065d  Inode: 5659849     Links: 2
Access: (0640/-rw-r-----)  Uid: ( 3457/mart_bda)   Gid: ( 3457/mart_bda)
Access: 2018-06-13 10:57:13.961409755 +0800
Modify: 2018-06-13 10:57:14.931383436 +0800
Change: 2018-06-13 10:58:11.382851699 +0800Birth: -

可以看到,两个文件的 inode 内容完全相同,且 Links 变成了 2修改任何一个文件名的内容,另一个文件名的内容也会同时改变,因为访问的就是硬盘中的同一块数据。

如果再将 test_file_hardlink 删掉,会使得 Links 变回 1。当这个值减到 0 时,说明没有文件名指向这个 inode,系统就会回收这个号码,以及所对应的 block 区域。

另外,对于目录的链接数,创建一个目录时,默认会生成两个目录项:. 和 .. 前者的 inode 号就是当前目录的 inode 号,等同于当前目录的硬链接;后者的 inode 号是父目录的 inode 号,等同于父目录的硬链接

因此,任何一个目录的硬链接总数,总是等于 2 加上它的子目录总数(含隐藏目录,且除去. 和 ..)。

软链接

软链接也可以通过不同的文件名访问同一块数据,但是与硬链接不同的是,两个文件名的 inode 是不一样的

那如何访问同一块区域呢?

比如文件 A 是文件 B 的软连接,那么文件 A 的内容存放的是文件 B 的路径名(可以通过这个找到文件 B 的目录项)。因此访问 A 时,会读取文件 B 的路径,进而读取文件 B 的内容。这样,对外表现来看,文件 A 和文件 B 的内容就相同了。类似于 windows 系统下的快捷方式

举个栗子

建立软链接的命令:

ln -s [source file] [new file]

如:

$ ll
total 489824
-rw-r----- 1 mart_bda mart_bda 501577774 Jun 13 11:21 test_file
$ ln -s test_file test_file_soft
$ ll -h -i
total 479M
5659853 -rw-r----- 1 mart_bda mart_bda 479M Jun 13 11:21 test_file
5659854 lrwxrwxrwx 1 mart_bda mart_bda    9 Jun 13 11:22 test_file_soft -> test_file

如果是对文件夹简历软链接,则为:

ln -s /tmp/test_directory ./

会自动地在当前目录建立一个文件夹 test_directory ,并指向 /tmp/test_directory

  • 两个文件的 inode 号是不同的。
  • 既然文件 A 是依赖文件 B 存在的,那么如果删除了文件 B,打开文件 A 就会报错:No such file or directory;
  • 如果删除了文件 A,则对文件 B 的打开无影响,因为只是删除了“快捷方式”而已。
  • 软连接的建立,不会影响到文件 B 的 inode 的任何信息,包括 Links。

硬链接和软链接的不同

  1. 本质不同:硬链接是指向同一个文件,软链接指向的不是同一个文件。
  2. 删除时:硬链接不受影响,软链接失效
  3. 创建链接时:创建硬链接链接数加1,创建软链接连接数不变
  4. 是否可以跨分区:硬链接不可以跨分区,软链接可以跨分区
  5. 目录是否可以创建链接:硬链接不可以对目录创建,软链接可以对目录创建
  6. 硬链接的inode号相同,软链接inode号不同

硬链接和软链接的占用空间分析

硬链接不占用磁盘空间,软链接占用的空间只是存储路径所占用的极小空间。

ll –h 或者 ls –h这命令进行统计文件总大小的时候并不是从磁盘进行统计的,而是根据文件属性中的大小叠加得来的。而硬链接的文件属性中的大小就是就是inode号对应的数据块的大小,所以total中进行统计就把各个文件属性中的大小加起来作为总和,这种统计是不标准,也不具有代表性的,

真正的查看某个文件夹占用磁盘空间大小命令是:du –h 这个命令是从磁盘上进行统计,不会被文件的属性中大小影响,所以更准确

硬链接及软连接引出的inode相关推荐

  1. linux与linux的连接,linux 硬链接与软连接

    硬链接与软连接的创建: 创建连接用到的命令是 ln, 带选项 -s 是 创建symbolic link 软连接, 不带 -s 是创建硬链接. 硬链接与软连接的区别: 硬链接与源文件的 inode 相同 ...

  2. 硬链接与软连接的区别_(转)

    首先我们需要了解linux下硬链接以及软连接的基本概念. 硬链接:新建的文件是已经存在的文件的一个别名,当原文件删除时,新建的文件仍然可以使用. 软链接:也称为符号链接,新建的文件以"路径& ...

  3. 硬链接和软连接 linux 的ln命令

    (一) 硬链接和软链接(符号链接) linux系统给每个文件都有一个编号,成为索引节点号(inode index) . linux系统中每个文件都有文件名和数据.数据包括用户数据 (user data ...

  4. linux中硬链接和软连接的区别

    硬链接: 硬链接是原始文本的一个镜像副本,创建硬链接后,如果把原始文件删除,连接文件也不会受到影响,因为此时原始文件和链接文件,互为镜像副本, 为什么要创建链接文件而不直接复制文件呢? 当你需要将同一 ...

  5. linux什么是硬链接和软连接区别,Linux硬链接和软连接的区别与总结

    图示软硬链接的区别 有关硬链接的总结 具有相同inode节点号的多个文件互为硬链接文件: 删除硬链接文件或者删除源文件任意之一,文件实体并未被删除: 只有删除了源文件和所有对应的硬链接文件,文件实体才 ...

  6. 硬链接和软连接的区别

    硬链接和软连接区别: 1.本质:硬链接:同一个多个名字,软连接不同文件 2.跨分区:硬链接不能夸分区,软连接可以跨分区 3.目录创建 硬链接不能创建lls 4.相互关系,软连接依赖原始文件 5.ind ...

  7. 【转】关于硬链接与软连接占用磁盘空间问题的分析研究

    转自:https://blog.51cto.com/jk6627/1949090 @迁行 感谢原作者. 在学习过硬链接和软连接的知识后,我们在做实验的过程中会发现,创建的硬链接会占用磁盘的空间,而我们 ...

  8. 硬链接和软连接(符号链接)

    硬链接:不同路径的文件指定的是同一个inode硬链接不能跨分区存在硬链接不能链接到目录(要避免循环引用)删除硬链接只会减少文件被硬链接的次数,源文件不会动. 软链接:是一个独立的文件,有自己独立的in ...

  9. linux 下建立硬链接和软连接

    对于一个文件来说,有唯一的索引接点(inode)与之对应,而对于一个索引接点号,却可以有多个文件名与之对应.因此,在磁盘上的同一个文件可以通过不同的路径去访问该文件.注意在Linux下是一切皆文件的啊 ...

最新文章

  1. ASP.NET页生命周期概述
  2. Laravel 5.5 使用 Passport 实现 Auth 认证
  3. java线程锁机制_多线程之锁机制
  4. 数据库 / 事务的 ACID
  5. 线性代数 —— 线性基与前缀线性基
  6. OSChina 周三乱弹——真相往往令人内牛满面
  7. python 文本相似度现状_python文本相似度分析
  8. java table 数据绑定,ireport5.6使用table组件,如何用table显示javaBean数据源
  9. scrapy简单爬取图片
  10. 5 个关键点!优化你的 UI 原型设计
  11. 圆弧周长公式_弧长计算公式的公式
  12. Statement cancelled due to timeout or client request 异常的修复【已解决】
  13. 亿阳信通南宁 java笔试_亿阳信通面试笔试题及答案
  14. 麻省理工学院公开课:计算机科学及编程导论
  15. 华为云系统繁忙,请稍后再试(0356034)账号升级错误
  16. 分享苹果电脑和乔布斯的十项成功秘诀
  17. 阿里云服务(一)—ECS和VPC
  18. iOS自动构建以及打包命令(xcodebuild,xcrun)
  19. 祝全天下老师教师节快乐
  20. linux注册域名命令,Linux基础命令---显示域名ypdomainname

热门文章

  1. nodejs 使用http进行post或get请求(携带cookie)
  2. Ler(一) stdlib.h,stdio.h,string.h头文件
  3. 改写中文句子的软件-修改文章句子的软件
  4. 【热文】 为什么很多硅谷工程师偏爱 OS X,而不是 Linux 或 Windows?
  5. 解决Could not find method ndkVersion() for arguments on object of type com.android.build.问题
  6. iSpiik产品说:抖音-信息浓度大师连续播放功能?
  7. 互联网摸鱼日报(2023-01-31)
  8. 基于三层交换机--NAT、VRRP技术的综合运用
  9. 台式高端计算机,台电27英寸一体机电脑 台式机性能高端体验
  10. 有趣的Python爬虫-原神角色查询程序