了解如何使用链接从Linux文件系统中的多个位置访问文件,从而使日常任务变得更轻松。在我为opensource.com撰写的关于Linux文件系统各个方面的文章中,包括Linux的EXT4文件系统的历史、特性和最佳实践;在Linux中管理设备;Linux文件系统概述和用户指南:逻辑卷管理,我已经简要提到了Linux文件系统的一个有趣特性,它通过允许用户从多个位置访问Linux文件目录树中的文件来简化一些任务。Linux文件系统中有两种链接:硬链接和软链接。虽然两者有很大不同,但都用于解决类似的问题。它们都提供对单个文件的多个目录条目(引用)的访问,但实现方式却大不相同。链接的力量赋予了Linux文件系统灵活性,因为一切都是文件。例如,我发现某些程序需要特定版本的库才能运行。用升级后的库替换旧库时,程序会崩溃,提示旧版本库丢失。通常,库名称的唯一变化是版本号。出于直觉,我只是向程序添加了一个新的库链接,以旧库命名。我尝试再次启动该程序并且运行良好。一个程序就是一个游戏,每个人都明白每个玩家都会努力让游戏继续下去。事实上,几乎所有的应用程序链接库都使用一个通用的命名约定。链接名包括主版本号,链接指向的文件的文件名也包括次版本号。又如,为了满足Linux文件系统规范,将程序的一些必要文件从一个目录移动到另一个目录。系统将指向这些文件的链接存储在旧目录中,以便向后兼容无法获取这些文件新位置的程序。.如果您对/lib64目录做一个长列表,您会发现很多这样的例子。lrwxrwxrwx.1rootroot36Dec82016cracklib_dict.hwm->../../usr/share/cracklib/pw_dict.hwmlrwxrwxrwx.1rootroot36Dec82016cracklib_dict.pwd->../../usr/share/cracklib/pw_dict.pwdlrwxrwxroot3.8rootpwx6.1./../usr/share/cracklib/pw_dict.pwilrwxrwxrwx.1rootroot27Jun92016libaccountsservice.so.0->libaccountsservice.so.0.0.0-rwxr-xr-x.1rootroot288456Jun92016libaccountsservice.so.0.0.0lrwxrwxrwx1root7acl.so.0.0.0lrwxrwxrwx1root7acl.1.1.0-rwxr-xr-x1rootroot36472May1711:47libacl.so.1.1.0lrwxrwxrwx.1rootroot15Feb42016libaio.so.1->libaio.so.1.0.1-rwxr-xr-x.1rootroot6224Feb420160libaio.so.1。0-rwxr-xr-x.1rootroot6224Feb42016libaio.so.1.0.1lrwxrwxrwx.1rootroot30Jan1616:39libakonadi-calendar.so.4->libakonadi-calendar.so.4.14.26-rwxr-xr-x.1rootroot816160Jan1616.endso:39libakoncal4.14.26lrwxrwxrwx.1rootroot29Jan1616:39libakonadi-contact.so.4->libakonadi-contact.so.4.14.26/lib64上图/lib64目录列表中的一些链接,文文件模式的第一个字母l(小写字母l)表示这是一个软链接(也称为符号链接)和硬链接。事实上,每个文件都有一个inode,其中包含有关文件的信息,包括文件的位置。上述文章中的图2显示了指向inode的单个目录条目。每个文件至少有一个目录项指向描述该文件信息的索引节点。目录项是一个硬链接,因此每个文件至少有一个硬链接。如下图1所示,多个目录项指向同一个inode。这些目录条目是硬链接。我在三个目录条目中使用波浪号(~)的缩写,这是用户目录的约定,因此波浪号在本例中等同于/home/user。值得注意的是,第四个目录条目是一个完全不同的目录,/home/shared,可能是该机器上用户的共享文件目录。图1硬链接仅限于单个文件系统。这里的“文件系统”是指挂载在特定挂载点上的分区或逻辑卷,在本例中为/home。这是因为inode编号在每个文件系统中都是唯一的。而在不同的文件系统中,例如/var或/opt,将会有与/home中相同的inode编号。因为所有硬链接都指向包含文件元信息的单个inode,所以作为文件一部分的属性(如所有权、权限和指向该inode的硬链接数)对于每个硬链接都没有区别。这是文件具有的一组属性。唯一区分这些文件的是inode信息中包含的文件名。基于同一目录中不能存在重复文件名的事实,链接到同一目录中单个文件/inode的硬链接必须具有不同的文件名。文件的硬链接数可以通过ls-l查看。如果想查看实际的节点号,可以使用ls-li命令。硬链接和软链接(也称为符号链接)的区别在于,硬链接直接指向文件所属的inode,而软链接直接指向目录项,即指向一个硬链接。因为软链接指向文件的硬链接而不是文件的inode,所以它们不依赖于inode编号,这使得它们可以跨不同的文件系统、分区和逻辑卷工作。软链接的缺点是一旦它指向的硬链接被删除或重命名,软链接就失效了。虽然软链接还在,但是它指向的硬链接已经不存在了。幸运的是,ls命令可以在其列表中以红底白字高亮显示损坏的软链接。实验项目:链接实验我认为了解链接用法及其差异的最简单方法是自己构建一个项目。该项目应以非root用户身份在空目录中完成。我为这个实验创建了一个~/temp目录,你也可以这样做。这样做为项目创建了一个安全的环境,并为程序运行提供了一个新的空目录,这样这里只存储与程序相关的文件。初始工作首先,在您将要试验的目录中为该项目中的任务创建一个临时目录,确保当前工作目录(PWD)是您的主目录,然后键入以下命令。mkdirtemp使用此命令将当前工作目录更改为~/temp。要开始cdtemp实验,我们需要创建一个我们可以链接到的文件,以下命令将完成这项工作并用内容填充它。du-h>main.file.txt使用ls-llonglistname确认文件已正确创建。结果应该和我的差不多。请注意,文件大小只有7个字节,但您的可能会相差1-2个字节。[dboth@davidtemp]$ls-ltotal4-rw-rw-r--1dbothdboth7Jun1307:34main.file.txt在列表中,文件模式字符串后面的数字1表示文件上存在的硬链接数。现在应该是1,因为我们还没有对这个测试文件做任何硬链接。尝试使用硬链接硬链接创建一个指向相同inode的新目录条目,当向文件添加硬链接时,您会看到链接数量增加。确保当前工作目录仍然是~/temp。创建到main.file.txt的硬链接并查看该目录中的文件列表。[dboth@davidtemp]$lnmain.file.txtlink1.file.txt[dboth@davidtemp]$ls-ltotal8-rw-rw-r--2dbothdboth7Jun1307:34link1.file.txt-rw-rw-r--2dbothdboth7Jun1307:34main.file.txt目录中的两个文件都有两个链接并且大小相同,时间戳也是如此。这是一个带有索引节点和两个硬链接(即文件的目录条目)的文件。然后创建该文件的硬链接并列出目录列表的内容。您可以创建硬链接:link1.file.txt或main.file.txt。[dboth@davidtemp]$lnlink1.file.txtlink2.file.txt;ls-ltotal16-rw-rw-r--3dbothdboth7Jun1307:34link1.file.txt-rw-rw-r--3dbothdboth7Jun1307:34link2.file.txt-rw-rw-r--3dbothdboth7Jun1307:34main.file.txt注意这个目录下的每个硬链接必须使用不同的名称,因为同一个目录下的两个文件不能有相同的文件名。尝试创建一个与现有链接同名的硬链接。[dboth@davidtemp]$lnmain.file.txtlink2.file.txtln:failedtocreatehardlink'link2.file.txt':Fileexists显然不起作用,因为link2.file.txt已经存在。到目前为止,我们只在同一目录中创建了硬链接,然后在临时目录的父目录(您的主目录)中创建了一个链接。[dboth@davidtemp]$lnmain.file.txt../main.file.txt;ls-l../main*-rw-rw-r--4dbothdboth7Jun1307:34main.file.txt上面的ls命令显示了main。file.txt文件确实存在于主目录中,并且与临时目录中的文件名相匹配。当然它们不是不同的文件,它们是同一个文件的两个链接,指向同一个文件的目录入口。为了帮助说明下一点,将一个非链接文件添加到临时目录。[dboth@davidtemp]$touchunlinked.file;ls-ltotal12-rw-rw-r--4dbothdboth7Jun1307:34link1.file.txt-rw-rw-r--4dbothdboth7Jun1307:34link2.file.txt-rw-rw-r--4dbothdboth7Jun1307:34main.file.txt-rw-rw-r--1dbothdboth0Jun1408:18unlinked.file使用ls命令的i选项查看inode的硬链接号和新建文件的硬链接号。[dboth@davidtemp]$ls-litotal12657024-rw-rw-r--4dbothdboth7Jun1307:34link1.file.txt657024-rw-rw-r--4dbothdboth7Jun1307:34link2.file.txt657024-rw-rw-r--4dbothdboth7Jun1307:341307.file.txt657863-rw-rw-r--1dbothdboth0Jun1408:18unlinked.file注意上面filemode左边的数字657024,这是三个硬链接文件引用的同一个文件的inode号。也可以使用i选项查看master目录下创建的链接的节点号,和这个值一样。虽然只有一个链接的inode编号与其他inode编号不同,但您在系统上看到的inode编号可能与本文中的不同。然后更改其中一个硬链接文件的大小。[dboth@davidtemp]$df-h>link2.file.txt;ls-litotal12657024-rw-rw-r--4dbothdboth1157Jun1414:14link1.file.txt657024-rw-rw-r--4dbothdboth1157Jun1414:14link2.file.txt657024-rw-rw-r--4dbothdboth1157Jun1414:14main.file.txt657863-rw-rw-r--1dbothdboth0Jun1408:18unlinked.file所有硬链接文件现在都比以前大了,因为多个目录条目链接到同一个文件。下一个实验将在我的计算机上得到这个结果,因为我的/tmp目录位于一个单独的逻辑卷上。如果您在不同的分区上有单独的逻辑卷或文件系统(如果不使用逻辑卷),请确保您可以访问该分区或逻辑卷,如果不能,您可以在您的计算机上安装一个U盘,如果上述方式适合您,你可以进行这个实验。尝试在/tmp目录中创建一个链接到~/temp目录(或文件系统所在的任何位置)中的文件。[dboth@davidtemp]$lnlink2.file.txt/tmp/link3.file.txtln:failedtocreatehardlink'/tmp/link3.file.txt'=>'link2.file.txt':Invalidcross-devicelink为什么会出现这个错误??原因是每个单独的可挂载文件系统都有自己的一组索引节点号。在整个Linux文件系统结构中简单地通过文件的inode编号引用文件会使系统感到困惑,因为相同的inode编号将存在于每个已安装的文件系统中。有时你可能想找到一个inode的所有硬链接。您可以使用ls-li命令。然后使用find命令查找所有硬链接的节点号。[dboth@davidtemp]$find.-inum657024./main.file.txt./link1.file.txt./link2.file.txt注意find命令找不到属于该节点的四个硬链接,因为我们是在~/中查看临时目录。find命令仅在当前工作目录及其子目录中查找文件。要查找所有硬链接,我们可以使用以下命令,将您的主目录指定为起始搜索条件。[dboth@davidtemp]$find~-samefilemain.file.txt/home/dboth/temp/main.file.txt/home/dboth/temp/link1.file.txt/home/dboth/temp/link2.file.txt/home/dboth/main.file.txt如果您是非超级用户并且没有权限,您可能会看到一条错误消息。此命令还使用-samefile选项而不是指定文件的索引节点号。如果您知道其中一个硬链接名称,效果就像使用索引节点号一样简单。尝试使用软链接正如您刚刚看到的,硬链接不能跨文件系统边界创建,即在逻辑卷或文件系统中从一个文件系统到另一个文件系统。软链接解决了这个问题。虽然它们可以用于相同的目的,但它们非常不同,了解这些差异很重要。让我们通过在~/temp目录中创建一个符号链接来开始我们的探索。[dboth@davidtemp]$ln-slink2.file.txtlink3.file.txt;ls-litotal12657024-rw-rw-r--4dbothdboth1157Jun1414:14link1.file.txt657024-rw-rw-r--4dbothdboth1157Jun1414:14link2.file。txt658270lrwxrwxrwx1dbothdboth14Jun1415:21link3.file.txt->link2.file.txt657024-rw-rw-r--4dbothdboth1157Jun1414:14main.file.txt657863-rw-rw-r--1dbothdboth0Jun1408。没有变化,硬链接的数量也没有变化。新创建的符号链接具有不同的索引节点号658270。名为link3.file.txt的软链接指向文件link2.file.txt。使用cat命令查看link3.file.txt文件的内容。符号链接的inode信息以字母l(小写字母l)开头,表示该文件实际上是一个符号链接。上例中软链接文件link3.file.txt的大小只有14个字节。这是文本内容link3.file.txt的大小,这个目录条目的实际内容。目录项link3.file.txt不指向索引节点;它指向另一个目录条目,这在跨文件系统建立链接时很有用。现在尝试创建一个符号链接,之前在/tmp目录中尝试过。[dboth@davidtemp]$ln-s/home/dboth/temp/link2.file.txt/tmp/link3.file.txt;ls-l/tmp/link*lrwxrwxrwx1dbothdboth31Jun1421:53/tmp/link3.file.txt->/home/dboth/temp/link2.file.txt删除链接删除硬链接或它引用的文件时,需要考虑一些问题。首先,让我们删除硬链接文件main.file.txt。请注意,每个指向inode的目录条目都是一个硬链接。[dboth@davidtemp]$rmmain.file.txt;ls-litotal8657024-rw-rw-r--3dbothdboth1157Jun1414:14link1.file.txt657024-rw-rw-r--3dbothdboth1157Jun1414:14link2.file.txt658270lwxrwxrwx1dboth1dboth3file.J21dboth1dboth15J2txt->link2.file.txt657863-rw-rw-r--1dbothdboth0Jun1408:18unlinked.filemain.file.txt是创建文件时创建的第一个硬链接。现在删除它,硬盘上仍然有原始文件和数据以及所有剩余的硬链接。要删除原始文件,您必须删除指向它的所有硬链接。现在删除link2.file.txt硬链接文件。[dboth@davidtemp]$rmlink2.file.txt;ls-litotal8657024-rw-rw-r--3dbothdboth1157Jun1414:14link1.file.txt658270lrwxrwxrwx1dbothdboth14Jun1415:21link3.file.txt->link2.file.txt-r-r-65wroth14-14:14dbothdunth1414main.file.txt657863-rw-rw-r--1dbothdboth0Jun1408:18unlinked.file注意软链接的变化。删除软链接指向的硬链接会使软链接失效。在我的系统上,断开的链接以颜色突出显示,并且指向目标的硬链接闪烁。如果需要修复这个损坏的软链接,需要在同一目录下创建一个与旧链接同名的硬链接,只要不是所有的硬链接都被删除即可。您还可以重新创建链接本身,该链接保持相同的名称但指向其余硬链接之一。当然,如果软链接不再需要,可以使用rm命令删除。unlink命令对于删除文件和链接也很有用。它非常简单,没有选项,就像rm命令一样。但是,它更准确地反映了删除的基本过程,因为它删除了目录条目到被删除文件的链接。写在***在我长期使用这两种类型的链接之后,我开始了解它们的功能和特性。我为我教授的Linux课程编写了一个实验项目,以充分理解链接的工作原理,我希望能提高您的理解。(标题图片:PaulLewin,修改自Opensource.com。CCBY-SA2.0)
