硬链接和软连接


linux文件链接分硬链接和软链接。。软链接又叫符号链接,类似windows下的快捷方式。 而硬链接又叫物理链接,通过不同的文件名关联到同一个文件inode。
通过ln命令可以建立链接,ln命令常用格式如下:

              [root@root ~]# ln [-sf] 链接目标文件 链接文件
              选项与参数:
              -s :ln默认创建文件的硬链接,-s选项创建文件的符号链接symbolic link,即软链接;
              -f :如果链接文件存在,就先将链接文件删除后再建立!
            
在用户家目录下建立/etc/crontab文件的硬链接:
              [root@initroot ~]# ln /etc/crontab .
            
在用户家目录下建立/etc/crontab文件的软链接sl_crontab:
              [root@initroot ~]# ln -s /etc/crontab sl_crontab
            

我们已经多次提到过,一个文件对应一个inode,inode中记录了文件内容的block编号,通过inode就可以找到文件内容。 那么怎么找到一个文件的inode呢?当然是通过文件名和inode的对应表,通过文件的文件名就可以找到该文件的inode。 而文件名和inode的对应表存在哪里呢?当然是存在目录文件中了。这样我们就能通过文件的路径,从根目录一层一层找到该文件了。 那么有没有可能有多个文件名对应同一个inode呢?答案是肯定的。如果一个文件名file1对应了一个已经存在的文件file0的inode, 那么file1就是file0的硬链接,也就是说file1和file0同时关联到同一个inode。 我们通过ln命令建立文件的硬链接和软连接。
ls命令加上-i选项即可查看文件的inode编号, 我们先观察/etc/crontab文件的详细信息:

              [root@initroot ~]# ls -il /etc/crontab
                1048732 -rw-r--r-- 1 root root 722 Nov 16  2017 /etc/crontab
            
注意/etc/crontab文件的inode编号为1048732,硬链接数为1.
在用户家目录下建立/etc/crontab文件的硬链接:
              [root@initroot ~]# ln /etc/crontab .
            
在用户家目录下建立/etc/crontab文件的硬链接:
              [root@initroot ~]# ln /etc/crontab .
            
观察三个文件的详细信息:
              [root@initroot ~]# ls -il /etc/crontab crontab
              1048732 -rw-r--r-- 2 root root 722 Nov 16  2017 crontab
              1048732 -rw-r--r-- 2 root root 722 Nov 16  2017 /etc/crontab
            
/root/crontab是/etc/crontab的硬链接,我们发现这两个文件属性信息一模一样,两个文件对应一个inode编号1048732, 由于有两个文件名同时链接到一个inode,所以硬链计数为2。
图.硬链接文件读取示意图
如果将其中一个文件删除,文件的inode与block都还是存在的! 只是文件的链接计数会减一。 不管通过哪个文件名来编辑文件,最终的数据都会写入到相同的inode与block中。
建立硬链接并没有实际创建新文件,只是在目录文件中增加了一个文件名和inode的关联记录。 大部分情况下不会额外占用block,当然可能会增加目录的block,比如建立硬链接时, 刚好目录的block已经填满,这时候就需要为目录增加一个block来记录文件名关连性。 不过hard link所用掉的关连数据量很小,所以通常对磁盘空间的影响微乎其微。
不过硬链接也有一些限制:
不能跨文件系统,
不能对目录建立硬链接。
不能跨Filesystem还好理解,不能硬链接目录是因为如果使用hard link链接到目录, 链接的数据需要连同被链接目录底下的所有数据都建立链接, 举例来说,如果要将/etc使用硬链接建立一个/etc_hd目录时,那么在/etc_hd目录下的所有文件名都要与/etc目录下的文件名建立hard link, 而不是仅连结到/etc_hd与/etc。 并且,未来如果需要在/etc_hd目录下建立新文件时,连带/etc目录下的数据又得要建立一次hard link, 因此复杂度会大大增加。所以,目前暂时还不支持对目录建立 hard link!
这里要注意虽然不能对目录建立硬链接。但是目录也是有硬链接计数的。我们通过一个实验来观察目录的硬链接计数。
我们知道一个空目录里面默认有两个隐藏文件.与..。.表示当前目录,.表示上一级目录。
所以如果我们用mkdir命令创建一个新目录testdir,那么基本上会有三个东西:
/tmp/testdir
/tmp/testdir/.
/tmp/testdir/..
而其中/tmp/testdir与/tmp/testdir/. 其实是一个文件!都代表该目录。而/tmp/testdir/..则表示上一级目录/tmp。 所以当我们新建一个目录时, 新目录的硬链接计数为2 ,而上层目录的硬链接数就会增加1。 我们先查看/tmp目录的硬链接计数为17:
              [root@initroot ~]# ls -ld /tmp/
              drwxrwxrwt 17 root root 200704 Jan 11 14:01 /tmp/
            
在/tmp目录下新建目录testdir:
              [root@initroot ~]# mkdir /tmp/testdir
            
再次观察/tmp目录的硬链接计数变为18了:
              [root@initroot ~]# ls -ld /tmp/
              drwxrwxrwt 18 root root 200704 Jan 11 14:01 /tmp/
            
而新建目录testdir的硬链接计数为2:
              [root@initroot ~]# ls -ld testdir/
              drwxr-xr-x 2 root root 4096 Jan 11 14:01 testdir/
              [root@initroot ~]# cd testdir/
              [root@initroot ~]# ls -al
              total 204
              drwxr-xr-x  2 root root   4096 Jan 11 14:01 .
              drwxrwxrwt 18 root root 200704 Jan 11 14:14 ..
            

软连接又叫符号链接,类似windows下的快捷方式。硬链接文件没有自己的inode和block,而是和链接的目标文件共用inode和block。 而软连接文件则有自己的inode和block.
在用户家目录下建立/etc/crontab文件的软链接并观察文件详情:

              [root@initroot ~]# ln -s /etc/crontab sl_crontab
              [root@initroot ~]# ll -i /etc/crontab /root/sl_crontab
              1048732 -rw-r--r-- 2 root root 722 Nov 16  2017 /etc/crontab
              410492 lrwxrwxrwx 1 root root  12 Jan 11 13:44 /root/sl_crontab -> /etc/crontab
            
/root/sl_crontab为指向/etc/crontab的软链接,我们发现两个文件的inode编号并不相同,文件属性也不一样。 所以这是两个相互独立的文件,我们发现软链接文件的大小为12bytes,而文件名"/etc/crontab"的字符长度正好是12, 软链接文件中内容存放的正是链接的目标文件名。通过这个文件名就可以找到软连接所链接的目标文件了。 如果目标文件(/etc/crontab)被删除了,那么就无法通过软连接读取到目标文件了!
通过vim编辑软连接文件/root/sl_crontab,其实编辑的是软连接指向的目标文件/etc/crontab。 Symbolic link所建立的文件为一个独立的新文件,所以会占用掉inode与block! 似乎hard link看上去比Symbolic link更安全,因为即使某一个目录下的文件数据被删掉了, 只要有任何一个目录下存在该文件的硬链接文件,那么该文件就不会被彻底删除,只是减少一个硬链接计数。 例如上面的/etc/crontab与/root/crontab指向同一个文件inode,如果删除了/etc/crontab文件,其实只是将/etc目录下crontab文件的硬链接计数减一, crontab所在的inode与block都没有被删除,直到硬链接计数为0,才真正的删除该文件!
但是由于Hard Link的限制较多,无法跨文件系统,也不能建立目录硬链接。所以Symbolic Link的使用更为广泛。
我们在linux下建立链接,通常就是指建立软链接。

initroot编辑整理,转载请注明www.initroot.com

100次点赞 100次阅读