You've successfully subscribed to The Daily Awesome
Great! Next, complete checkout for full access to The Daily Awesome
Welcome back! You've successfully signed in.
Success! Your account is fully activated, you now have access to all content.
Success! Your billing info is updated.
Billing info update failed.
深入理解 Linux 链接

深入理解 Linux 链接

. 5 min read

Windows文件管理中有一个非常实用的功能——快捷方式,它为一份文件提供了多个不同的入口,并以此进行同步。而快捷方式在我看来是对Linux中符号链接功能的一种泛化。(与之类似的,还有MacOS中的别名Alias功能)

在Unix操作系统中,文件的引入使独立于进程之外信息得以长期存储,文件作为进程创建信息的逻辑单元可被多个进程并发使用,简单来说,UNIX 系统中除进程之外的一切皆是文件,Linux 也保持了这一特性, 并引入了目录(文件夹)这一概念便于文件管理。

注:包括键盘鼠标在内的所有设备,依然被操作系统视为文件,并可以被打开进而通讯

Linux的文件数据

Linux将文件数据分为用户数据(user data)与元数据(metadata)两部分,如下图,

Linux将文件数据分为用户数据与文件数据
Linux将文件数据分为用户数据与文件数据

其中文件名(filename)很好理解,而数据块(data blocks)中存储的为文件的具体内容,于此同时,索引节点(inode)则存储了除文件名外的附加属性(文件大小,创建时间,修改时间,所有者,权限等等等等)。同时也很容易理解,对于Linux而言,inode才是文件的唯一标识(我们可以很容易地在不同目录创建同名文件)。

在Linux中可以使用stat <filename>查看Inode编号及属性;或使用 ls -i 列出当前目录下所有文件的 Inode 编号

下面是一个简单的例子,可以看到即使重命名文件并不会改变文件的Inode(Change部分当然除外)

 [email protected]$ 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: -
 [email protected]$ ls -i 
25614222880720159 prime.py 
 [email protected]$ mv prime.py prime.py.test 
 [email protected]$ stat prime.py 
stat: cannot stat 'prime.py': No such file or directory 
[email protected]$ 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: -
 [email protected]$ 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,而软链接显然不能(目录没有)。实际上,软链接严格来说也是文件,只不过它的数据区块存储的是其指向的文件路径,如下所示,

图 2. 软链接的访问
软链接与硬链接对文件的访问
 [email protected]  ~/tmp  echo "Hello world" >> test 
 [email protected]  ~/tmp  ll 
total 0 
-rw-rw-rw- 1 jiachen jiachen 12 Oct  4 15:16 test
 [email protected]  ~/tmp  cat test          
Hello world 
 [email protected]  ~/tmp  ln -s ~/tmp/test ~/tmp/sln_test  
 [email protected]  ~/tmp  cat sln_test     
Hello world 
 [email protected]  ~/tmp  mv test test_mv 
 [email protected]  ~/tmp  cat sln_test 

很显然,当原始文件的路径改变后,则软连接失效,从前面的例子可以知道硬链接显然不会。

在实际使用中,软连接当然可以链接已有的软链接,但个人不建议这样做,否则容易增加文件系统维护的复杂度。

并且强烈建议使用绝对路径进行链接,以免因为用户切换而造成不可预知的问题。

常用命令

...

Reference: