在GNU/Linux中删除硬链接,以及inode的话题

4 min

language: ja bn en es hi pt ru zh-cn zh-tw

大家好,我是无能。
好久没用ln命令创建链接了,结果不小心忘记删除-s选项,创建了硬链接,所以现在要删除这些不必要的硬链接。

创建硬链接

不带选项执行ln命令会创建硬链接。

alleycat:[haturatu]:~/git/hardlink$ ls
alleycat:[haturatu]:~/git/hardlink$ touch hardlink1
alleycat:[haturatu]:~/git/hardlink$ echo "You are an idiot" >> hardlink1 
alleycat:[haturatu]:~/git/hardlink$ cat hardlink1 
You are an idiot
alleycat:[haturatu]:~/git/hardlink$ ls -la
合计 12
drwxr-xr-x   2 haturatu haturatu 4096  1月 12 15:00 .
drwxr-xr-x 114 haturatu haturatu 4096  1月 12 15:00 ..
-rw-r--r--   1 haturatu haturatu   17  1月 12 15:01 hardlink1

我尝试像上面那样创建了一个文件。

alleycat:[haturatu]:~/git/hardlink$ ln hardlink1 hardlink2
alleycat:[haturatu]:~/git/hardlink$ ls -la
合计 16
drwxr-xr-x   2 haturatu haturatu 4096  1月 12 15:02 .
drwxr-xr-x 114 haturatu haturatu 4096  1月 12 15:00 ..
-rw-r--r--   2 haturatu haturatu   17  1月 12 15:01 hardlink1
-rw-r--r--   2 haturatu haturatu   17  1月 12 15:01 hardlink2

这样就创建了硬链接。
然后,我们来看看下面的标准输出。

-rw-r--r--   2 haturatu haturatu   17  1月 12 15:01 hardlink1
-rw-r--r--   2 haturatu haturatu   17  1月 12 15:01 hardlink2

这个-rw-r--r-- 2中的2是硬链接的数量。与创建硬链接之前相比,您应该能看到这个值增加了。
而且,这仅仅是链接,所以不会占用额外的磁盘空间。它存储的是单一数据,inode号是相同的,指向同一个文件。
使用-i选项来确认inode号。

alleycat:[haturatu]:~/git/hardlink$ ls -lia
合计 16
13238408 drwxr-xr-x   2 haturatu haturatu 4096  1月 12 15:02 .
11406555 drwxr-xr-x 114 haturatu haturatu 4096  1月 12 15:00 ..
13265123 -rw-r--r--   2 haturatu haturatu   17  1月 12 15:01 hardlink1
13265123 -rw-r--r--   2 haturatu haturatu   17  1月 12 15:01 hardlink2

什么是inode?

这仅仅取决于文件系统,所以上面是在GNU/Linux环境下。如果是BSD系的文件系统,可能会是vnode;如果是ZFS,则可能是znode等,略有不同。但从历史上看,可以理解为它是对原始UNIX文件系统的扩展。

而且,与符号链接不同,即使删除了hardlink1hardlink2仍然存在;即使删除了hardlink2hardlink1也仍然存在。从这一点来说,解释可能是文件系统管理着文件本身,但这仍然有点难以理解,对吧?
然而,这样看来硬链接很方便,但符号链接可以引用不同磁盘上的文件,而硬链接不能在不同磁盘上创建。
简单来说,结合之前的解释,文件系统是基于单一磁盘的inode标准,所以如果是不同磁盘,则超出了该文件系统的管辖范围,无法在层级结构上引用。
因此,如果文件存在于不同磁盘上,就需要创建符号链接。

而且,从文件系统的角度来看,我们日常使用它是在磁盘恢复、恢复操作时,通过引用过去的inode信息来识别哪个inode号的文件被创建或删除。
这里有一个陷阱,如果文件被覆盖,这个inode号也会被更新。也就是说,在编写备份脚本等时,可能需要注意确保脚本不会进行覆盖操作。(我曾经犯过一次错误)

识别具有相同inode号的文件

可以使用find命令进行确认。

alleycat:[haturatu]:~/git/hardlink$ find . -inum 13265123
./hardlink2
./hardlink1

那么,现在我来删除hardlink1

alleycat:[haturatu]:~/git/hardlink$ rm -i hardlink1
rm: 删除普通文件 'hardlink1' 吗? y
alleycat:[haturatu]:~/git/hardlink$ ls -lai
合计 12
13238408 drwxr-xr-x   2 haturatu haturatu 4096  1月 12 15:23 .
11406555 drwxr-xr-x 114 haturatu haturatu 4096  1月 12 15:00 ..
13265123 -rw-r--r--   1 haturatu haturatu   17  1月 12 15:01 hardlink2
alleycat:[haturatu]:~/git/hardlink$ cat hardlink2 
You are an idiot

这样,硬链接的数量也变成了1,并且确认了通过ln hardlink1 hardlink2创建的hardlink1的链接,以及拥有与hardlink1相同信息的hardlink2存在并拥有相同的数据。

在实际应用中

虽然很久没接触了,但如果想在同一磁盘内复制大文件但又想减少磁盘消耗,使用硬链接似乎是个好方法。
嗯,也许这不是一个需要经常刻意使用的东西,但它能让人稍微了解文件系统的结构,所以我觉得很有趣。


那么,下次再见。
请多关照。

Related Posts