前言

在 Linux 底下的连结档有两种,一种是类似 Windows 的快捷方式功能的文件,可以让你快速的链接到目标文件(或目录),这种是软链接; 另一种则是透过文件系统的 inode 连结来产生新档名,而不是产生新文件!这种称为硬链接 (hard link)。 这两种玩意儿是完全不一样的东西呢!现在就分别来谈谈。

Hard Link (实体链接, 硬式连结或实际连结)

在前一小节当中,我们知道几件重要的信息,包括:

每个文件都会占用一个 inode ,文件内容由 inode 的记录来指向;
想要读取该文件,必须要经过目录记录的文件名来指向到正确的 inode 号码才能读取。
也就是说,其实文件名只与目录有关,但是文件内容则与 inode 有关。那么想一想, 有没有可能有多个档名对应到同一个 inode 号码呢?有的!那就是 hard link 的由来。 所以简单的说:hard link 只是在某个目录下新增一笔档名链接到某 inode 号码的关连记录而已。

举个例子来说,假设我系统有个 /root/crontab 他是 /etc/crontab 的实体链接,也就是说这两个档名连结到同一个 inode , 自然这两个文件名的所有相关信息都会一模一样(除了文件名之外)。实际的情况可以如下所示:

[root@www ~]# ln /etc/crontab . <==创建实体链接的命令
[root@www ~]# ll -i /etc/crontab /root/crontab
1912701 -rw-r--r-- 2 root root 255 Jan 6 2007 /etc/crontab
1912701 -rw-r--r-- 2 root root 255 Jan 6 2007 /root/crontab

你可以发现两个档名都连结到 1912701 这个 inode 号码,所以您瞧瞧,是否文件的权限/属性完全一样呢? 因为这两个『档名』其实是一模一样的『文件』啦!而且你也会发现第二个字段由原本的 1 变成 2 了! 那个字段称为『连结』,这个字段的意义为:『有多少个档名链接到这个 inode 号码』的意思。 如果将读取到正确数据的方式画成示意图,就类似如下画面:

  实体链接的文件读取示意图
上图的意思是,你可以透过 1 或 2 的目录之 inode 指定的 block 找到两个不同的档名,而不管使用哪个档名均可以指到 real 那个 inode 去读取到最终数据!那这样有什么好处呢?最大的好处就是『安全』!如同上图中, 如果你将任何一个『档名』删除,其实 inode 与 block 都还是存在的! 此时你可以透过另一个『档名』来读取到正确的文件数据喔!此外,不论你使用哪个『档名』来编辑, 最终的结果都会写入到相同的 inode 与 block 中,因此均能进行数据的修改哩!

一般来说,使用 hard link 配置链接文件时,磁盘的空间与 inode 的数目都不会改变! 我们还是由图 来看,由图中可以知道, hard link 只是在某个目录下的 block 多写入一个关连数据而已,既不会添加 inode 也不会耗用 block 数量哩!

备注:
hard link 的制作中,其实还是可能会改变系统的 block 的,那就是当你新增这笔数据却刚好将目录的 block 填满时,就可能会新加一个 block 来记录文件名关连性,而导致磁盘空间的变化!不过,一般 hard link 所用掉的关连数据量很小,所以通常不会改变 inode 与磁盘空间的大小喔!

由上图其实我们也能够知道,事实上 hard link 应该仅能在单一文件系统中进行的,应该是不能够跨文件系统才对! 因为上图就是在同一个 filesystem 上嘛!所以 hard link 是有限制的:

不能跨 Filesystem;
不能 link 目录。

不能跨 Filesystem 还好理解,那不能 hard link 到目录又是怎么回事呢?这是因为如果使用 hard link 链接到目录时, 链接的数据需要连同被链接目录底下的所有数据都创建链接,举例来说,如果你要将 /etc 使用实体链接创建一个 /etc_hd 的目录时,那么在 /etc_hd 底下的所有档名同时都与 /etc 底下的檔名要创建 hard link 的,而不是仅连结到 /etc_hd 与 /etc 而已。 并且,未来如果需要在 /etc_hd 底下创建新文件时,连带的, /etc 底下的数据又得要创建一次 hard link ,因此造成环境相当大的复杂度。 所以啰,目前 hard link 对于目录暂时还是不支持的啊!

Symbolic Link (符号链接,亦即是快捷方式)

相对于 hard link , Symbolic link 可就好理解多了,基本上, Symbolic link 就是在创建一个独立的文件,而这个文件会让数据的读取指向他 link 的那个文件的档名!由于只是利用文件来做为指向的动作, 所以,当来源档被删除之后,symbolic link 的文件会『开不了』, 会一直说『无法开启某文件!』。实际上就是找不到原始『档名』而已啦!

举例来说,我们先创建一个符号链接文件链接到 /etc/crontab 去看看:

[root@www ~]# ln -s /etc/crontab crontab2
[root@www ~]# ll -i /etc/crontab /root/crontab2
1912701 -rw-r--r-- 2 root root 255 Jan 6 2007 /etc/crontab
654687 lrwxrwxrwx 1 root root 12 Oct 22 13:58 /root/crontab2 -> /etc/crontab

由上表的结果我们可以知道两个文件指向不同的 inode 号码,当然就是两个独立的文件存在! 而且连结档的重要内容就是他会写上目标文件的『文件名』, 你可以发现为什么上表中连结档的大小为 12 bytes 呢? 因为箭头(-->)右边的档名『/etc/crontab』总共有 12 个英文,每个英文占用 1 个 byes ,所以文件大小就是 12bytes了!

关于上述的说明,我们以如下图示来解释:

图 符号链接的文件读取示意图
由 1 号 inode 读取到连结档的内容仅有档名,根据档名链接到正确的目录去取得目标文件的 inode , 最终就能够读取到正确的数据了。你可以发现的是,如果目标文件(/etc/crontab)被删除了,那么整个环节就会无法继续进行下去, 所以就会发生无法透过连结档读取的问题了!

这里还是得特别留意,这个 Symbolic Link 与 Windows 的快捷方式可以给他划上等号,由 Symbolic link 所创建的文件为一个独立的新的文件,所以会占用掉 inode 与 block 喔!

由上面的说明来看,似乎 hard link 比较安全,因为即使某一个目录下的关连数据被杀掉了, 也没有关系,只要有任何一个目录下存在着关连数据,那么该文件就不会不见!举上面的例子来说,我的 /etc/crontab 与 /root/crontab 指向同一个文件,如果我删除了 /etc/crontab 这个文件,该删除的动作其实只是将 /etc 目录下关于 crontab 的关连数据拿掉而已, crontab 所在的 inode 与 block 其实都没有被变动喔!

不过由于 Hard Link 的限制太多了,包括无法做『目录』的 link , 所以在用途上面是比较受限的!反而是 Symbolic Link 的使用方面较广喔!好了, 说的天花乱坠,看你也差不多快要昏倒了!没关系,实作一下就知道怎么回事了!要制作连结档就必须要使用 ln 这个命令呢!

ln

[root@www ~]# ln [-sf] 来源文件 目标文件

选项与参数:
-s :如果不加任何参数就进行连结,那就是hard link,至于 -s 就是symbolic link
-f :如果 目标文件 存在时,就主动的将目标文件直接移除后再创建! 范例一:将 /etc/passwd 复制到 /tmp 底下,并且观察 inode 与 block
[root@www ~]# cd /tmp
[root@www tmp]# cp -a /etc/passwd .
[root@www tmp]# du -sb ; df -i .
18340 . <==先注意一下这里的容量是多少!
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/hdc2 2560864 149738 2411126 6% /
# 利用 du 与 df 来检查一下目前的参数~那个 du -sb
# 是计算整个 /tmp 底下有多少 bytes 的容量啦!

范例二:将 /tmp/passwd 制作 hard link 成为 passwd-hd 文件,并观察文件与容量

[root@www tmp]# ln passwd passwd-hd
[root@www tmp]# du -sb ; df -i .
18340 .
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/hdc2 2560864 149738 2411126 6% /
# 仔细看,即使多了一个文件在 /tmp 底下,整个 inode 与 block 的容量并没有改变! [root@www tmp]# ls -il passwd*
586361 -rw-r--r-- 2 root root 1945 Sep 29 02:21 passwd
586361 -rw-r--r-- 2 root root 1945 Sep 29 02:21 passwd-hd
# 原来是指向同一个 inode 啊!这是个重点啊!另外,那个第二栏的连结数也会添加!

范例三:将 /tmp/passwd 创建一个符号链接

[root@www tmp]# ln -s passwd passwd-so
[root@www tmp]# ls -li passwd*
586361 -rw-r--r-- 2 root root 1945 Sep 29 02:21 passwd
586361 -rw-r--r-- 2 root root 1945 Sep 29 02:21 passwd-hd
586401 lrwxrwxrwx 1 root root 6 Oct 22 14:18 passwd-so -> passwd
# passwd-so 指向的 inode number 不同了!这是一个新的文件~这个文件的内容是指向
# passwd 的。passwd-so 的大小是 6bytes ,因为 passwd 共有六个字符之故 [root@www tmp]# du -sb ; df -i .
18346 .
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/hdc2 2560864 149739 2411125 6% /
# 呼呼!整个容量与 inode 使用数都改变啰~确实如此啊!

范例四:删除源文件 passwd ,其他两个文件是否能够开启?

[root@www tmp]# rm passwd
[root@www tmp]# cat passwd-hd
......正常显示完毕!
[root@www tmp]# cat passwd-so
cat: passwd-so: No such file or directory
[root@www tmp]# ll passwd*
-rw-r--r-- 1 root root 1945 Sep 29 02:21 passwd-hd
lrwxrwxrwx 1 root root 6 Oct 22 14:18 passwd-so -> passwd
# 怕了吧!符号链接果然无法开启!另外,如果符号链接的目标文件不存在,
# 其实档名的部分就会有特殊的颜色显示喔!

要注意啰!使用 ln 如果不加任何参数的话,那么就是 Hard Link 啰!如同范例二的情况,添加了 hard link 之后,可以发现使用 ls -l 时,显示的 link 那一栏属性添加了!而如果这个时候砍掉 passwd 会发生什么事情呢?passwd-hd 的内容还是会跟原来 passwd 相同,但是 passwd-so 就会找不到该文件啦!

而如果 ln 使用 -s 的参数时,就做成差不多是 Windows 底下的『快捷方式』的意思。当你修改 Linux 下的 symbolic link 文件时,则更动的其实是『原始档』, 所以不论你的这个原始档被连结到哪里去,只要你修改了连结档,原始档就跟着变啰! 以上面为例,由于你使用 -s 的参数创建一个名为 passwd-so 的文件,则你修改 passwd-so 时,其内容与 passwd 完全相同,并且,当你按下储存之后,被改变的将是 passwd 这个文件!

此外,如果你做了底下这样的连结:

ln -s /bin /root/bin
那么如果你进入 /root/bin 这个目录下,『请注意呦!该目录其实是 /bin 这个目录,因为你做了连结档了!』所以,如果你进入 /root/bin 这个刚刚创建的链接目录, 并且将其中的数据杀掉时,嗯! /bin 里面的数据就通通不见了!这点请千万注意!所以赶紧利用『rm /root/bin 』 将这个连结档删除吧!

基本上, Symbolic link 的用途比较广,所以您要特别留意 symbolic link 的用法呢!未来一定还会常常用到的啦!

关于目录的 link 数量:
或许您已经发现了,那就是,当我们以 hard link 进行『文件的连结』时,可以发现,在 ls -l 所显示的第二字段会添加一才对,那么请教,如果创建目录时,他默认的 link 数量会是多少? 让我们来想一想,一个『空目录』里面至少会存在些什么?呵呵!就是存在 . 与 .. 这两个目录啊! 那么,当我们创建一个新目录名称为 /tmp/testing 时,基本上会有三个东西,那就是:

/tmp/testing
/tmp/testing/.
/tmp/testing/..
而其中 /tmp/testing 与 /tmp/testing/. 其实是一样的!都代表该目录啊~而 /tmp/testing/.. 则代表 /tmp 这个目录,所以说,当我们创建一个新的目录时, 『新的目录的 link 数为 2 ,而上一级目录的 link 数则会添加 1 』 不信的话,我们来作个测试看看:

[root@www ~]# ls -ld /tmp
drwxrwxrwt 5 root root 4096 Oct 22 14:22 /tmp
[root@www ~]# mkdir /tmp/testing1
[root@www ~]# ls -ld /tmp
drwxrwxrwt 6 root root 4096 Oct 22 14:37 /tmp
[root@www ~]# ls -ld /tmp/testing1
drwxr-xr-x 2 root root 4096 Oct 22 14:37 /tmp/testing1

瞧!原本的所谓上一级目录 /tmp 的 link 数量由 5 添加为 6 ,至于新目录 /tmp/testing 则为 2 ,这样可以理解目录的 link 数量的意义了吗? ^_^

转自 http://vbird.dic.ksu.edu.tw/linux_basic/0230filesystem_2.php

Linux学习之CentOS(十四)----磁盘管理之 硬连接与软件连接(转)的更多相关文章

  1. Linux学习之CentOS(十二)----磁盘管理之 认识ext文件系统(转)

    认识ext文件系统 硬盘组成与分割 文件系统特性 Linux 的 EXT2 文件系统(inode) 与目录树的关系 EXT2/EXT3 文件的存取与日志式文件系统的功能 Linux 文件系统的运行 挂 ...

  2. Linux学习之CentOS(十五)----磁盘管理之 启动挂载(转)

    启动挂载 /etc/fstab 及 /etc/mtab 刚刚上面说了许多,那么可不可以在启动的时候就将我要的文件系统都挂好呢?这样我就不需要每次进入 Linux 系统都还要在挂载一次呀!当然可以啰!那 ...

  3. Linux学习之CentOS(十二)------磁盘管理之 磁盘的分区、格式化、挂载(转)

    磁盘分区.格式化.挂载磁盘分区    新增分区    查询分区    删除分区磁盘格式化    mkfs    mke2fs磁盘挂载与卸载    mount    umount 磁盘的分区.格式化.挂 ...

  4. Linux学习总结(十四)—— 查看CPU信息

    文章首发于[博客园-陈树义],点击跳转到原文Linux学习总结(十四)-- 查看CPU信息. Linux学习总结(十四)-- 查看CPU信息 商用服务器CPU最常用的是 Intel Xeon 系列,该 ...

  5. Linux学习总结(七)-磁盘管理 du df fdisk

    一 命令df df,即disk free,可用来查看当前系统的挂载情况,也可以用来查看整体磁盘的使用情况df 不带参数,默认以KB单位显示df -i -----查看inodes 使用情况,要清楚理解i ...

  6. Linux学习笔记(十四)磁盘管理(二):格式化、挂载以及Swap分区

    一.格式化 第一种写法 mkfs.文件系统 [分区名称(设备文件路径)] 例如:对sdb硬盘的第一个分区以ext3文件系统进行格式化 第二种写法 mkfs -t 文件系统  [分区名称(设备文件路径) ...

  7. Linux命令(二十四) 磁盘管理命令(二) mkfs,mount

    一.格式化文件系统 mkfs 当完成硬盘分区以后要进行硬盘的格式化,mkfs系列对应的命令用于将硬盘格式化为指定格式的文件系统.mkfs 本身并不执行建立文件系统的工作,而是去调用相关的程序来执行.例 ...

  8. Linux学习之CentOS(二)----远程登录管理工具SecureCRT的使用

    [声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/3 ...

  9. Linux学习之CentOS(十)--虚拟机下的CentOS如何上网

    原地址:http://www.cnblogs.com/xiaoluo501395377/archive/2013/04/05/3001148.html 这篇随笔应该说跟CentOS的学习关系不是很大, ...

随机推荐

  1. DDD实战进阶第一波(二):开发一般业务的大健康行业直销系统(搭建支持DDD的轻量级框架一)

    要实现软件设计.软件开发在一个统一的思想.统一的节奏下进行,就应该有一个轻量级的框架对开发过程与代码编写做一定的约束. 虽然DDD是一个软件开发的方法,而不是具体的技术或框架,但拥有一个轻量级的框架仍 ...

  2. Hadoop安装-部署-测试

    一:准备Linux环境[安装略]        a.修改主机名                vim /etc/sysconfig/network                NETWORKING= ...

  3. WPF 自定义ComboBox样式

    一.ComboBox基本样式 ComboBox有两种状态,可编辑和不可编辑状态.通过设置IsEditable属性可以切换控件状态. 先看基本样式效果: 基本样式代码如下: <!--ComboBo ...

  4. 新概念英语(1-131)Don't be so sure

    Lesson 131 Don't be so sure! 别那么肯定! Listen to the tape then answer this question. What's the problem ...

  5. SQL Server 2012 管理新特性:AlwaysOn 可用性组

    SQL Server 2012 新特性(一)管理新特性:AlwaysOn 一.准备环境 1.准备4台计算机 域控制器DC1,IP地址192.168.1.1 主节点SQL1:IP地址192.168.1. ...

  6. linux ubunt 安装软件的前期准备——更新源的更换

    如果是高手,请翻到页面最下方,更换更新源的总结,直接操作即可 可能会优点啰嗦,但是认真看,一定能解决问题~~希望对大家有帮助~ 最近在熟悉linux环境,自己安装了一个ubuntu虚拟机. 很多朋友问 ...

  7. tar磁带归档

    一:压缩.解压 1.compress/uncompress/zcat -d:解压 -c:输出到终端,不删除原文件 -v:显示详细信息 2.gzip/ungzip/zcat -d:解压 -c:将压缩或解 ...

  8. uvalive 3602 DNA Consensus String

    https://vjudge.net/problem/UVALive-3602 题意: 给定m个长度均为n的DNA序列,求一个DNA序列,使得它到所有的DNA序列的汉明距离最短,若有多个解则输出字典序 ...

  9. 使用LINGO来解决0/1背包算法问题

    1.问题说明 0/1背包问题:我们有n种物品,物品j的重量为wj,价格为pj.我们假定所有物品的重量和价格都是非负的.背包所能承受的最大重量为W.如果限定每种物品只能选择0个或1个,则问题称为0-1背 ...

  10. scrapy爬取全部知乎用户信息

    # -*- coding: utf-8 -*- # scrapy爬取全部知乎用户信息 # 1:是否遵守robbots_txt协议改为False # 2: 加入爬取所需的headers: user-ag ...