0%

深入理解Linux文件系统--软链接与硬链接

inode

硬盘的最小存储单位是扇区(Sector),块(Block)由多个扇区组成。文件数据存储在块中。块的最常见的大小是4Kb,约为8个连续的扇区组成(每个扇区存储512字节)。计算机的内存是基于字节编址的,就像一个文件可能会占用多个Block,但是一个块只能存放一个文件。

虽然,我们将文件存储在了块(Block)中,但是我们还需要一个空间来存储文件的元数据(Meta Data),如:某个文件被分成几块、每一块在的地址、文件拥有者,创建时间,权限,大小等。这种存储文件元信息的区域就叫inode,译为索引节点(Index Node)。 每个文件都指向一个inode,存储文件的元信息。

可以使用stat命令可以查看文件的inode信息。每个inode都有一个号码,Linux/Unix操作系统不使用文件名来区分文件,而是使用inode号码区分不同的文件。

$ stat helloworld.txt
File: helloworld.txt
Size: 12 Blocks: 8 IO Block: 4096 regular file
Device: 259,2 Inode: 1188276 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 1000/ xuranus) Gid: ( 1000/ xuranus)
Access: 2022-07-16 09:57:23.513371618 +0800
Modify: 2022-07-16 09:57:23.513371618 +0800
Change: 2022-07-16 09:57:23.513371618 +0800
Birth: 2022-07-16 09:57:23.513371618 +0800

软链接和硬链接

  • 软链接(soft link),又称符号链接(symbolic link),是指向原文件的链接
  • 硬链接(hard link),是对元文件的一种镜像拷贝

创建软链接helloworld_softlink.txt指向源文件helloworld.txt

$ ln -s helloworld.txt helloworld_softlink.txt

ls -l可以看到它们的指向关系:

$ ls -l
total 4
lrwxrwxrwx 1 xuranus xuranus 14 Jul 16 09:58 helloworld_softlink.txt -> helloworld.txt
-rw-r--r-- 1 xuranus xuranus 12 Jul 16 09:57 helloworld.txt

stat查看他们具体的元数据:

$ stat helloworld.txt
File: helloworld.txt
Size: 12 Blocks: 8 IO Block: 4096 regular file
Device: 259,2 Inode: 1188276 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 1000/ xuranus) Gid: ( 1000/ xuranus)
Access: 2022-07-16 09:57:23.513371618 +0800
Modify: 2022-07-16 09:57:23.513371618 +0800
Change: 2022-07-16 09:57:23.513371618 +0800
Birth: 2022-07-16 09:57:23.513371618 +0800

$ stat helloworld_softlink.txt
File: helloworld_softlink.txt -> helloworld.txt
Size: 14 Blocks: 0 IO Block: 4096 symbolic link
Device: 259,2 Inode: 1188277 Links: 1
Access: (0777/lrwxrwxrwx) Uid: ( 1000/ xuranus) Gid: ( 1000/ xuranus)
Access: 2022-07-16 09:58:15.537706288 +0800
Modify: 2022-07-16 09:58:13.537853704 +0800
Change: 2022-07-16 09:58:13.537853704 +0800
Birth: 2022-07-16 09:58:13.537853704 +0800

可以看到两者拥有不同的大小、权限、inode号,说明符号链接和源文件指向不同的inode。

接下来创建硬链接helloworld_hardlink.txt也指向helloworld.txt

$ ln helloworld.txt helloworld_hardlink.txt   

再次ls -l,发现原文件helloworld.txt和硬链接helloworld_hardlink.txt的硬连接数增加成了2。
$ ls -l                                    
total 8
-rw-r--r-- 2 xuranus xuranus 12 Jul 16 09:57 helloworld_hardlink.txt
lrwxrwxrwx 1 xuranus xuranus 14 Jul 16 09:58 helloworld_softlink.txt -> helloworld.txt
-rw-r--r-- 2 xuranus xuranus 12 Jul 16 09:57 helloworld.txt

ls -i可以看到原文件helloworld.txt和硬链接helloworld_hardlink.txt拥有同样的inode号
$ ls -i                               
1188276 helloworld_hardlink.txt 1188277 helloworld_softlink.txt 1188276 helloworld.txt

stat检查属性会发现原文件helloworld.txt和硬链接helloworld_hardlink.txt所有的元数据也都相同:
$ stat helloworld_hardlink.txt             
File: helloworld_hardlink.txt
Size: 12 Blocks: 8 IO Block: 4096 regular file
Device: 259,2 Inode: 1188276 Links: 2
Access: (0644/-rw-r--r--) Uid: ( 1000/ xuranus) Gid: ( 1000/ xuranus)
Access: 2022-07-16 09:57:23.513371618 +0800
Modify: 2022-07-16 09:57:23.513371618 +0800
Change: 2022-07-16 09:58:46.795994588 +0800
Birth: 2022-07-16 09:57:23.513371618 +0800

$ stat helloworld.txt
File: helloworld.txt
Size: 12 Blocks: 8 IO Block: 4096 regular file
Device: 259,2 Inode: 1188276 Links: 2
Access: (0644/-rw-r--r--) Uid: ( 1000/ xuranus) Gid: ( 1000/ xuranus)
Access: 2022-07-16 09:59:27.228482936 +0800
Modify: 2022-07-16 09:57:23.513371618 +0800
Change: 2022-07-16 09:58:46.795994588 +0800
Birth: 2022-07-16 09:57:23.513371618 +0800

删除远文件helloworld.txt,可以看到helloworld_hardlink.txt的硬链接计数降为了1

$ rm helloworld.txt 
$ ls -l
total 4
-rw-r--r-- 1 xuranus xuranus 12 Jul 16 09:57 helloworld_hardlink.txt
lrwxrwxrwx 1 xuranus xuranus 14 Jul 16 09:58 helloworld_softlink.txt -> helloworld.txt

此时硬链接helloworld_hardlink.txt还可以访问,而软链接`helloworld_softlink.txt已经无法找到指向的文件了:
$ cat helloworld_hardlink.txt 
Hello World
$ cat helloworld_softlink.txt
cat: helloworld_softlink.txt: No such file or directory

对于一个目录,分别创建软链接和硬链接。软链接创建成功,硬链接创建失败:

$ mkdir dir 
$ echo 'Hello World' > dir/helloworld.txt
$ ln -s dir dirsl
$ ln dir dirsl
ln: dir: hard link not allowed for directory


软链接指向一个新的inode,所以拥有独立的元数据,软链接文件的内容是指向文件的地址,所以源文件删除、重命名或移动位置都会导致软链接失效。硬链接则和原文件指向同一个inode,创建硬链接会增加对应inode的硬链接计数。

文件系统初始化时就会为磁盘分配inode区和数据区,由于inode的索引号只在同一个文件系统有意义,所以硬链接的指向不能跨文件系统。

总结软链接的区别如下:

硬链接 软链接
只能针对文件 能针对文件和目录
不能跨文件系统 能跨文件系统
删除源文件硬链接数减1 删除源文件软链接失效
和源文件指向同一个inode,共享的元数据 有自己独有的inode,独立的元数据

当软链接指向一个目录的时候,不能使用rm -rf删除软链接,这会导致删除指向的目录。正确的方法是直接rm删除软链接

参考资料

Disqus评论区没有正常加载,请使用科学上网