Windows文件管理中有一个非常实用的功能——快捷方式,它为一份文件提供了多个不同的入口,并以此进行同步。而快捷方式在我看来是对Linux中符号链接功能的一种泛化。(与之类似的,还有MacOS中的别名Alias功能)
在Unix操作系统中,文件的引入使独立于进程之外信息得以长期存储,文件作为进程创建信息的逻辑单元可被多个进程并发使用,简单来说,UNIX 系统中除进程之外的一切皆是文件,Linux 也保持了这一特性, 并引入了目录(文件夹)这一概念便于文件管理。
注:包括键盘鼠标在内的所有设备,依然被操作系统视为文件,并可以被打开进而通讯
Linux的文件数据
Linux将文件数据分为用户数据(user data)与元数据(metadata)两部分,如下图,
Linux将文件数据分为用户数据与文件数据
其中文件名(filename)很好理解,而数据块(data blocks)中存储的为文件的具体内容,于此同时,索引节点(inode)则存储了除文件名外的附加属性(文件大小,创建时间,修改时间,所有者,权限等等等等)。同时也很容易理解,对于Linux而言,inode才是文件的唯一标识(我们可以很容易地在不同目录创建同名文件)。
在Linux中可以使用stat <filename>
查看Inode编号及属性;或使用 ls -i
列出当前目录下所有文件的 Inode 编号
下面是一个简单的例子,可以看到即使重命名文件并不会改变文件的Inode(Change部分当然除外)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
jiachen@DELL$ stat prime.py
File: prime.py
Size: 606 Blocks: 8 IO Block: 512 regular file
Device: 2h/2d Inode: 25614222880720159 Links: 1
Access: (0666/-rw-rw-rw-) Uid: ( 1000/ jiachen) Gid: ( 1000/ jiachen)
Access: 2019-10-04 14:48:59.779690000 +0800
Modify: 2019-10-04 14:48:59.781083800 +0800
Change: 2019-10-04 14:48:59.781083800 +0800
Birth: -
jiachen@DELL$ ls -i
25614222880720159 prime.py
jiachen@DELL$ mv prime.py prime.py.test
jiachen@DELL$ stat prime.py
stat: cannot stat 'prime.py': No such file or directory
jiachen@DELL$ stat prime.py.test
File: prime.py.test
Size: 606 Blocks: 8 IO Block: 512 regular file
Device: 2h/2d Inode: 25614222880720159 Links: 1
Access: (0666/-rw-rw-rw-) Uid: ( 1000/ jiachen) Gid: ( 1000/ jiachen)
Access: 2019-10-04 14:48:59.779690000 +0800
Modify: 2019-10-04 14:48:59.781083800 +0800
Change: 2019-10-04 14:49:58.919329800 +0800
Birth: -
jiachen@DELL$ ls -i
25614222880720159 prime.py.test
|
前面已经提到了,既然Linux使用Inode作为文件标识符,那么我们显然可以为其指定不同的入口来进入同一个数据区块。Linux的解决方案是链接,即赋予一个Inode多个文件名。
硬链接与软链接
链接的使用有非常多的优点,例如服务器证书安装中隐藏文件目录,增加安全权限,统一管理等,在目录管理中便于访问,在文件管理中节约存储,保证一致性等。
基于Inode的链接显然只能针对文件使用,为了将其拓展到对于目录的使用,Linux引入了硬链接和软链接两种概念。
软连接 |
硬链接 |
是否支持该特质 |
N |
Y |
文件属性必须相同(Inode, datablock) |
N |
Y |
文件必须存在 |
Y |
N |
跨文件系统链接 |
Y |
N |
链接目录 |
N |
N |
删除链接影响原始文件 |
以上是软连接与硬链接在表现上的不同,接下来让我们对其实现有一个大概的了解,增强对其表现的认识。
从前面的内容可以得知,硬链接指向了文件的Inode,而软链接显然不能(目录没有)。实际上,软链接严格来说也是文件,只不过它的数据区块存储的是其指向的文件路径,如下所示,
软链接与硬链接对文件的访问
1
2
3
4
5
6
7
8
9
10
11
|
jiachen@DELL ~/tmp echo "Hello world" >> test
jiachen@DELL ~/tmp ll
total 0
-rw-rw-rw- 1 jiachen jiachen 12 Oct 4 15:16 test
jiachen@DELL ~/tmp cat test
Hello world
jiachen@DELL ~/tmp ln -s ~/tmp/test ~/tmp/sln_test
jiachen@DELL ~/tmp cat sln_test
Hello world
jiachen@DELL ~/tmp mv test test_mv
jiachen@DELL ~/tmp cat sln_test
|
很显然,当原始文件的路径改变后,则软连接失效,从前面的例子可以知道硬链接显然不会。
在实际使用中,软连接当然可以链接已有的软链接,但个人不建议这样做,否则容易增加文件系统维护的复杂度。
并且强烈建议使用绝对路径进行链接,以免因为用户切换而造成不可预知的问题。
常用命令
...
Reference: