软链接与硬链接

上一篇文章已经向大家介绍了Linux系统中文件目录结构,见http://vinsent.blog.51cto.com/13116656/1959522 。基于次,这篇博客向大家介绍Linux文件系统中的软连接(也称:符号链接)和硬链接;主要包括软、硬连接的概念,软连接与硬链接的区别以及如何创建软、硬链接。该文章中引用了https://www.ibm.com/developerworks/cn/linux/l-cn-hardandsymb-links/  中的一些概念;如有侵权,敬请相告!立即删除。


一、相对路径与绝对路径

在介绍软硬链接之前,先向大家介绍相对路径与绝对路径;我们在Linux中进行目录切换,以及系统自带的大岁数库文件均是以相对路径形成的符号链接文件来实现的。而我们的操作大多数时候接触的都是硬链接,像切换目录(cd /etc/sysconfig/network-scripts/)、挂载文件(mount /dev/sdxx /mnt/)等等。

1、绝对路径

绝对路径即“路径绝对”,说明只有唯一的路径来到达我们的“目的地”。绝对路径是从根“/”开始的(如 /etc/rc.d/inittab)即只要一个路径是从根开始的,那么毫无疑问,它一定是绝对路径。例如:

[ root@vinsent ~ ]#
[ root@vinsent ~ ]#pwd             # 查看当前目录
/root
[ root@vinsent ~ ]#cd /etc/rc.d/init.d/  # 以绝对路径进入/etc/rc.d/init.d/目录
[ root@vinsent init.d ]#ls
functions  netconsole  network  README
[ root@vinsent init.d ]#pwd         # pwd 查看当前目录为/etc/rc.d/init.d/
/etc/rc.d/init.d
[ root@vinsent init.d ]#

2、相对路径

相对路径:顾名思义该路径是相对的,相对于某指定目录或当前虽在目录。相对路径是以.或 ..开始的,.表示用户当前操作所处的位置,而..表示上级目录;在路径中,.表示用户当前所处的目录,而 ..上级目录,要把.和..当做目录来看。例如:

[ root@vinsent init.d ]#
[ root@vinsent init.d ]#pwd      # 首先进入到了/etc/rc.d/init.d目录下,pwd查看当前目录
/etc/rc.d/init.d
[ root@vinsent init.d ]#cd ..     # ..代表上级目录,cd ..进入到/etc/rc.d目录下
[ root@vinsent rc.d ]#pwd
/etc/rc.d
[ root@vinsent rc.d ]#cd ..      
[ root@vinsent etc ]#pwd
/etc
[ root@vinsent etc ]#cd ../boot     # 从当前目录切换到boot目录下
[ root@vinsent boot ]#
[ root@vinsent boot ]#pwd          # pwd 查看当前目录为/boot
/boot
[ root@vinsent boot ]#

二、软连接与硬链接

1、硬链接

硬链接是通过索引节点进行的链接。在Linux中,多个文件指向同一个索引节点是允许的,像这样的链接就是硬链接。硬链接只能在同一文件系统中的文件之间进行链接,不能对目录进行创建。如果删除硬链接对应的源文件,则硬链接文件仍然存在,而且保存了原有的内容,这样可以起到防止因为误操作而错误删除文件的作用。 由于硬链接是有着相同 inode 号仅文件名不同的文件,因此,删除一个硬链接文件并不影响其他有相同 inode 号的文件;图解硬链接:

Linux中软、硬链接那些事儿_第1张图片

2、软链接

也称符号链接与硬链接不同,文件用户数据块中存放的内容是另一文件的路径名的指向。软链接就是一个普通文件,只是数据块内容有点特殊。软链接可对文件或目录创建。 软链接主要应用于以下两个方面:一是方便管理,例如可以把一个复杂路径下的文件链接到一个简单路径下方便用户访问;另一方面就是解决文件系统磁盘空间不足的情况。例如某个文件文件系统空间已经用完了,但是现在必须在该文件系统下创建一个新的目录并存储大量的文件,那么可以把另一个剩余空间较多的文件系统中的目录链接到该文件系统中,这样就可以很好的解决空间不足问题。删除软链接并不影响被指向的文件,但若被指向的原文件被删除,则相关软连接就变成了死链接。 使用-s选项的ln命令即可创建符号链接。下图是软连接的工作过程:

Linux中软、硬链接那些事儿_第2张图片

3、软连接与硬链接的异同

从软连接与硬链接的概念我们便能感受到这两者的不同;下面对其异同加以总结。由于硬链接是有着相同 inode 号仅文件名不同的文件,因此硬链接存在以下几点特性:

  • 文件有相同的 inode 及 data block;

  • 只能对已存在的文件进行创建;

  • 不能交叉文件系统进行硬链接的创建;

  • 不能对目录进行创建,只可对文件创建;

  • 删除一个硬链接文件并不影响其他有相同 inode 号的文件;

软链接与硬链接不同,若文件用户数据块中存放的内容是另一文件的路径名的指向,则该文件就是软连接。软链接就是一个普通文件,只是数据块内容有点特殊。软链接有着自己的 inode 号以及用户数据块因此软链接的创建与使用没有类似硬链接的诸多限制:

  • 软链接有自己的文件属性及权限等;

  • 可对不存在的文件或目录创建软链接;

  • 软链接可交叉文件系统;

  • 软链接可对文件或目录创建;

  • 创建软链接时,链接计数 i_nlink 不会增加;

  • 删除软链接并不影响被指向的文件,但若被指向的原文件被删除,则相关软连接被称为死链接(即 dangling link,若被指向路径文件被重新创建,死链接可恢复为正常的软链接)。

4、创建软链接和硬链接

介绍完了软连接与硬链接的概念以及其异同;接下带着大家一步一步创建软、硬链接,从实验中领会软、硬链接的不同。硬链接的使用“ln”来实现;软连接使用“ln -s”来实现。

#------------实验环境准备-----------#

[ root@vinsent ~ ]#
[ root@vinsent ~ ]#rm -rf /app/*     # 为了不影响实验,我们清空/app/目录
[ root@vinsent ~ ]#cd /app             # 切换到/app目录
[ root@vinsent app ]#ls
[ root@vinsent app ]#pwd
/app
[ root@vinsent app ]#mkdir -p /app/{a/{x/{m,n/k},y},b,c/{q,w/{e/yy,r}},d}  # 创建若干目录
[ root@vinsent app ]#tree /app         # tree查看/app的目录树结构
/app
├── a
│   ├── x
│   │   ├── m
│   │   └── n
│   │       └── k
│   └── y
├── b
├── c
│   ├── q
│   └── w
│       ├── e
│       │   └── yy
│       └── r
└── d

14 directories, 0 files
[ root@vinsent app ]#
[ root@vinsent app ]#cd /app/a/x/n/k       # 进入到/app/a/x/n/k 创建两个文件
[ root@vinsent k ]#touch 1.txt
[ root@vinsent k ]#touch 2.txt
[ root@vinsent k ]#cd /app/c/w/e/yy         # 进入到/app/c/w/e/yy 创建两个文件
[ root@vinsent yy ]#touch 11.txt
[ root@vinsent yy ]#touch 22.txt

#------------创建硬链接--------------#
[ root@vinsent ~ ]#ln /app/c/w/e/yy/11.txt /app/a/x/n/k/1bak.txt  # 创建硬链接
[ root@vinsent yy ]#ll
total 0
-rw-r--r--. 2 root root 0 Aug 28 21:43 11.txt   # 节点数增加到2
-rw-r--r--. 1 root root 0 Aug 28 21:43 22.txt
[ root@vinsent yy ]#cd /app/a/x/n/k/
[ root@vinsent k ]#ll
total 0
-rw-r--r--. 2 root root 0 Aug 28 21:43 1bak.txt  # 节点数增加到2 说明硬链接创建成功
-rw-r--r--. 1 root root 0 Aug 28 21:42 1.txt
-rw-r--r--. 1 root root 0 Aug 28 21:42 2.txt
[ root@vinsent k ]#echo 123634124 > 1bak.txt     # 改变文件 1bak.txt 内容
[ root@vinsent k ]#cat 1bak.txt
123634124
[ root@vinsent k ]#rm -rf 1bak.txt           # 删除该链接文件
[ root@vinsent k ]#cd /app/c/w/e/yy           # 切换到/app/c/w/e/yy目录下
[ root@vinsent yy ]#ll                  # 查看节点数减少
total 4
-rw-r--r--. 1 root root 7 Aug 28 21:54 11.txt
-rw-r--r--. 1 root root 0 Aug 28 21:43 22.txt
[ root@vinsent yy ]#cat 11.txt             # 查看源文件的内容并未发生改变
123124 
[ root@vinsent app ]#ln abc /etc/abc_bak        # 跨分区创建硬链接,提示错误
ln: failed to create hard link ‘/etc/abc_bak’ => ‘abc’: Invalid cross-device link

#------------创建软连接--------------#

[ root@vinsent init.d ]#cd /etc/rc.d/rc3.d/       # 切换到/etc/rc.d/rc3.d/ 
[ root@vinsent rc3.d ]#ll                # 软连接表现为一个目录指向另外一个目录
total 0
lrwxrwxrwx. 1 root root 20 Aug 14 11:09 K50netconsole -> ../init.d/netconsole
lrwxrwxrwx. 1 root root 17 Aug 14 11:09 S10network -> ../init.d/network
[ root@vinsent yy ]#ln -s  ../../../../c/w/e/yy/11.txt  ../../../../a/x/n/k/11bak.txt   # 创建软连接
[ root@vinsent yy ]#ll
total 4
-rw-r--r--. 1 root root 38 Aug 28 22:17 11.txt
-rw-r--r--. 1 root root  0 Aug 28 21:43 22.txt
[ root@vinsent yy ]#cd /app/a/x/n/k/
[ root@vinsent k ]#ll                # 查看软连接
total 0
lrwxrwxrwx. 1 root root 27 Aug 28 22:18 11bak.txt -> ../../../../c/w/e/yy/11.txt
-rw-r--r--. 1 root root  0 Aug 28 21:42 1.txt
-rw-r--r--. 1 root root  0 Aug 28 21:42 2.txt
[ root@vinsent k ]# 
[ root@vinsent k ]#cat 11bak.txt         # 查看文件内容
1sdfsaldfhaskdh
jashdkfj
kasdfk
23124
[ root@vinsent k ]#echo 82734 > 11bak.txt   # 修改文件内容
[ root@vinsent k ]#cat 11bak.txt 
82734
[ root@vinsent k ]#cd /app/c/w/e/yy/       # 切换回源目录
[ root@vinsent yy ]#ll              
total 4
-rw-r--r--. 1 root root 6 Aug 28 22:21 11.txt
-rw-r--r--. 1 root root 0 Aug 28 21:43 22.txt
[ root@vinsent yy ]#cat 11.txt          # 查看原文件内容,发现也被修改了;说明软连接是同一个文件
82734
[ root@vinsent yy ]#rm -rf 11.txt         # 删除原文件
[ root@vinsent yy ]#cd -             # 切换回上次所在的目录
/app/a/x/n/k
[ root@vinsent k ]#ll               # 查看链接文件,发现变红了;
total 0
lrwxrwxrwx. 1 root root 27 Aug 28 22:18 11bak.txt -> ../../../../c/w/e/yy/11.txt
[ root@vinsent k ]#cat 11bak.txt          # 查看文件 内容,提示出错
cat: 11bak.txt: No such file or directory
[ root@vinsent app ]#ln -s ../app/abc ../root/abc_bak  # 在不同分区创建软连接,成功了
[ root@vinsent app ]#cd /root
[ root@vinsent ~ ]#ll               # 不同分区创建软连接成功;说明可以跨分区
lrwxrwxrwx. 1 root root      10 Aug 28 22:28 abc_bak -> ../app/abc

补充说明:

  1. 当然软链接的用户数据也可以是一个绝对路径路径。如果不在同根下,软链接创建时原文件的路径指向使用绝对路径较好。这是使用相对路径创建的软链接被移动后该软链接文件将成为一个死链接,因为链接数据块中记录的亦是相对路径指向。如果链接文件与原文件在同个根下,那么用相对路径实现较好,他能完美实现整体迁移,不破坏结构,此时使用绝对路径将找不到原文件。故此;创建软连接时,建议视情况而定。

  2. 在软连接相对路径中,目标文件时相对当前目录而言的或者原文件所在的目录而言的;而原文件的路径是相对目标链接文件的路径而言的。可能你会觉得很难理解,下面以图解的方式帮大家一臂之力

Linux中软、硬链接那些事儿_第3张图片

三、本篇小结

本篇博客主要讲述了,什么是相对路径、绝对路径以及软连接、硬链接的相关概念与实现;相对路径是指:相对某目录或者当前位置而言的,比如..表示进入到上级目录,这是相对当前目录而言的;绝对路径,顾名思义是绝对的路径,你在任何目录下都能通过该路径进入到指定的目录下,例如:不管你在哪个目录下,只要在命令行输入cd /etc/rc.d/init.d便可进入到init.d目录下。硬链接的两文件都指向了某个数据块,本质是同一个文件,只是起了不同的名,没多一个硬链接,原文件和链接文件的链接数就会增加1,删除其中一个文件并不影响其他文件;硬链接有诸多限制,像不能跨分区,不能跨设备。软连接相对硬链接而言,则显得更加灵活,没有硬链接的限制条件,能跨分区、设备;但由于软连接的特性,也存在一些问题,像链接文件时一个指向原文件的指向,并不指向其数据块,所以删除原文件,那么链接文件将不能使用,编辑其中一个文件,访问另外一个文件将看到改变后的数据。到此为止,Linux文件系统中的一些基本概念就介绍完了,谢谢大家的阅读。