标签 符号链接 下的文章

链接一直是 UNIX 文件系统的一个独特的高级功能。

 title=

UNIX 和 Linux 用户发现链接有很多用途,特别是符号链接。我喜欢使用符号链接的一种方式是管理各种 IT 设备的配置备份。

我有一个目录结构,用来存放我的文档、更新及网络上其他和计算机和设备有关的文件。设备可以包括路由器、接入点、NAS 服务器和笔记本电脑,通常有不同的品牌和版本。配置备份本身可能在目录树的深处,例如 /home/alan/Documents/network/device/NetgearRL5000/config

为了简化备份过程,我在主目录中有一个名为 Configuration 的目录。我使用这个目录的符号链接来指向特定的设备目录:

:~/Configuration/ $ ls -F1
Router@
Accesspoint@
NAS@

注意ls 命令的 -F 选项在每个文件名上附加特殊字符以表示其类型。如上所示,@ 符号表示这些是链接。

创建一个链接

符号链接 Router 指向我的 Netgear RL5000 的 config 目录。创建它的命令是 ln -s

$ ln -s /home/alan/Documents/network/device/NetgearRL5000/config Router

然后,用 ls -l 看一下并确认:

:~/Configuration/ $ ls -l
Router -> /home/alan/Documents/network/device/NetgearRL5000/config
NAS -> /home/alan/Documents/network/device/NFSBox/config
...

这样做的好处是,当对这个设备进行维护时,我只需进入 ~/Configuration/Router

如果我决定用一个新的型号替换这个路由器,使用符号链接的第二个好处就很明显了。我可能会把旧的路由器改成一个接入点。因此,它的目录并没有被删除。相反,我有一个新的目录,对应于新的路由器,也许是华硕 DF-3760。我创建这个目录并确认它的存在:

$ mkdir -p ~/Documents/network/device/ASUSDF-3760/config
:~/Documents/network/device/ $ ls
NetgearRL5000
ASUSDF-3760
NFSBox
...

另一个例子是,如果你的办公室里有几个接入点。你可以使用符号链接在逻辑上代表每一个,用一个通用的名字,如 ap1ap2,等等,或者你可以使用描述性的词语,如 ap_floor2ap_floor3,等等。这样,当物理设备随时间变化时,你不必持续更新任何可能管理它们的进程,因为它们是在处理链接而不是实际的设备目录。

更新一个链接

由于我的主路由器已经改变,我想让路由器的符号链接指向它的目录。我可以使用 rmln 命令来删除和创建一个新的符号链接,但是有一种方法可以只用 ln 命令和几个选项就可以一步完成:

:~/Configuration/ $ ln -vfns ~/Documents/network/device/ASUSDF-3760/config/ Router
'Router' -> '/home/alan/Documents/network/device/ASUSDF-3760/config/'
:~/Configuration/ $ ls -l
Router -> /home/alan/Documents/network/device/ASUSDF-3760/config
NAS -> /home/alan/Documents/network/device/NFSBox/config

根据手册页,这些选项如下:

  • -v--verbose:打印每个链接文件的名称
  • -f--force:删除目标文件(有必要,因为已经存在一个链接)
  • -n--no-dereference:如果链接名是一个目录的符号链接,就把它当作一个正常的文件
  • -s--symbolic:制作符号链接而不是硬链接

总结

链接是 UNIX 和 Linux 文件系统中最强大的功能之一。其他操作系统也曾试图模仿这种能力,但由于他们的文件系统缺乏基本的链接设计,这些系统从来没有工作得那么好,也没有那么可用。

上面的演示只是利用链接在生活生产环境中无缝浏览不断变化的目录结构的众多可能性中的一种。链接提供了一个永远不会长期静态的组织所需的灵活性。


via: https://opensource.com/article/21/11/update-linux-file-system-link

作者:Alan Formy-Duval 选题:lujun9972 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

符号链接是指向另一个文件的 Linux 文件。如果删除了被引用的文件,符号链接会保留,但不会显示有问题,除非你尝试使用它。以下是查找和删除指向文件已被删除的符号链接的简单方法。

符号链接 symbolic link 在 Linux 系统上扮演了非常有用的角色。它们可以帮助你记住重要文件在系统上的位置,使你更容易访问这些文件,并让你不必为了更方便访问大文件而复制它们,从而节省了大量的空间。

什么是符号链接?

通常称它们为“符号链接”或“软链接”,符号链接是非常小的文件。实际上,符号链接真正包含的是它指向的文件的名称,通常包含路径(相对于当前位置或绝对路径)。如果有个名为 ref1 的文件指向名为 /apps/refs/ref-2020 的文件,那么 ref1 的长度将为 19 个字符,即使 ref-202 文件有 2TB。如果指向 ./ref-2020,那么长度仅为 10 个字符。如果指向 ref-2020,那么只有 8 个字节。

如果你执行 vi ref1 之类的命令(其中 ref1 是符号链接的名称),你将编辑 ref1 指向的文件,而不是符号链接本身的内容。Linux 系统知道如何使用符号链接,并且可以做正确的事。同样,如果你使用诸如 catmoreheadtail 之类的命令,那么将查看引用文件的内容。

另一方面,如果删除符号链接,你将删除该链接,而不是引用的文件。再说一次,Linux 知道怎么做。符号链接使得使用和共享文件更加容易,仅此而已。

符号链接损坏时

当一个符号链接所指向的文件从系统中删除或重新命名时,符号链接将不再起作用。符号链接只不过是存储在某个特定目录中的引用而已,它不会随着指向它的文件发生变化而更新或删除。它一直指向被引用的文件,即使这个文件早已消失。

如果你尝试使用指向一个不存在的文件的符号链接,那么将出现如下错误:

$ tail whassup
tail: cannot open 'whassup' for reading: No such file or directory

如果你尝试访问指向自身的符号链接(是的,奇怪的事情发生了),你将看到类似以下的内容:

$ cat loopy
cat: loopy: Too many levels of symbolic links
$ ls -l loopy
lrwxrwxrwx 1 shs shs 5 May 28 18:07 loopy -> loopy

而且,如果(上面的)长列表的第一个字母没有引起你的注意,这表示该文件是符号链接。rwxrwxrwx 权限是标准权限,并不反映符号链接指向的文件的权限。

查找损坏的符号链接

find 命令有一个选项,能让你找到指向不再存在的文件的符号链接。此命令列出当前目录中的符号链接:

$ find . -type l

l (小写字母 L)告诉 find 命令查找符号链接。

另一方面,下面的命令在当前目录中查找指向不存在的文件的符号链接:

$ find . -xtype l

为了避免在该命令尝试查找你无权检查的文件或目录时发生错误,你可以将所有错误输出到 /dev/null,如下所示:

$ find . -xtype l 2>/dev/null

你也可以使用此命令找到损坏的符号链接。它比前面的更长,但做的是同样的事情:

$ find . -type l ! -exec test -e {} \; -print 2>/dev/null

如何处理损坏的符号链接

除非你知道符号链接引用的文件会被替换,否则最好的方法是直接删除损坏的链接。实际上,如果需要,你可以使用一条命令查找并删除损坏的符号链接,如:

$ find . -xtype l 2>/dev/null -exec rm {} \;

该命令的 rm {} 部分会变成“删除文件”的命令

如果你想将符号链接与不同的文件相关联,你必须先删除该符号链接,然后重新创建它,使其指向新文件。这是一个例子:

$ rm ref1
$ ln -s /apps/data/newfile ref1

总结

符号链接使引用的文件更易于查找和使用,但有时它会比那些宣传去年已经关闭的餐馆的路标还过分。find 命令可以帮助你摆脱损坏的符号链接,或者提醒你没有你可能仍然需要的文件。


via: https://www.networkworld.com/article/3546252/how-to-find-and-remove-broken-symlinks-on-linux.html

作者:Sandra Henry-Stocker 选题:lujun9972 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

链接 Link 是一种快捷访问机制,它通过一个文件指向原始文件或目录的方式实现快捷访问,同时还记录了原始文件或目录的一些信息。

链接允许多个不同文件对同一个文件进行引用。

什么是软链接

符号链接 Symbolic Link (symlink),又称 软链接 Soft Link ,是一种特殊的文件,它指向 Linux 系统上的另一个文件或目录。

这和 Windows 系统中的快捷方式有点类似,链接文件中记录的只是原始文件的路径,并不记录原始文件的内容。

符号链接通常用于对库文件进行链接,也常用于链接日志文件和 网络文件系统 Network File System (NFS)上共享的目录。

什么是硬链接

硬链接是原始文件的一个镜像副本。创建硬链接后,如果把原始文件删除,链接文件也不会受到影响,因为此时原始文件和链接文件互为镜像副本。

为什么要创建链接文件而不直接复制文件呢?

当你需要将同一个文件保存在多个不同位置,而且还要保持持续更新的时候,硬链接的重要性就体现出来了。

如果你只是单纯把文件复制到另一个位置,那么另一个位置的文件只会保存着复制那一刻的文件内容,后续也不会跟随着原始文件持续更新。

而使用硬链接时,各个镜像副本的文件内容都会同时更新。

软链接和硬链接的区别

下表列出了软链接和硬链接之间的区别。

#软链接硬链接
1软链接类似于 Windows 系统中的快捷方式硬链接是原始文件的一个镜像副本
2软链接又称符号链接硬链接没有别名
3链接中任何一个文件发生改变,都会同步到连接中的其它文件和软链接一样
4软链接可以跨文件系统进行创建硬链接不可以跨文件系统进行创建
5软链接可以指向文件或目录硬链接只能指向文件
6链接文件和原始文件之间的 inode 和文件权限不完全一致链接文件和原始文件的 inode 和文件权限完全一致
7链接文件只记录原始文件的路径,不记录原始文件的内容链接文件记录了原始文件的内容
8如果原始文件被移除,软链接就会因为指向不存在的文件而失效。这被称为“ 挂起链接 hanging link 即使原始文件被移除,链接文件也不受影响。
9通过 ln -s <原始文件> <链接文件> 命令创建软链接通过 ln <原始文件> <链接文件> 命令创建硬链接
10软链接文件的文件权限中有一个特殊标记 l硬链接文件没有特殊标记
11通过 find / -type l 命令可以查找软链接文件通过 find / -samefile <原始文件> 命令可以查找硬链接文件
12通过 symlinks <目录> 命令可以查找失效的软链接硬链接不存在失效链接

via: https://www.2daygeek.com/difference-between-soft-link-vs-hard-link-linux/

作者:Magesh Maruthamuthu 选题:lujun9972 译者:HankChow 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

你可能有时需要在 Linux 上创建或者删除符号链接。如果有,你知道该怎样做吗?之前你做过吗?你踩坑没有?如果你踩过坑,那没什么问题。如果还没有,别担心,我们将在这里帮助你。

使用 rmunlink 命令就能完成移除(删除)符号链接的操作。

什么是符号链接?

符号链接(symlink)又称软链接,它是一种特殊的文件类型,在 Linux 中该文件指向另一个文件或者目录。它类似于 Windows 中的快捷方式。它能在相同或者不同的文件系统或分区中指向一个文件或着目录。

符号链接通常用来链接库文件。它也可用于链接日志文件和挂载的 NFS(网络文件系统)上的文件夹。

什么是 rm 命令?

rm 命令 被用来移除文件和目录。它非常危险,你每次使用 rm 命令的时候要非常小心。

什么是 unlink 命令?

unlink 命令被用来移除特殊的文件。它被作为 GNU Gorutils 的一部分安装了。

1) 使用 rm 命令怎样移除符号链接文件

rm 命令是在 Linux 中使用最频繁的命令,它允许我们像下列描述那样去移除符号链接。

# rm symlinkfile

始终将 rm 命令与 -i 一起使用以了解正在执行的操作。

# rm -i symlinkfile1
rm: remove symbolic link ‘symlinkfile1’? y

它允许我们一次移除多个符号链接:

# rm -i symlinkfile2 symlinkfile3

rm: remove symbolic link ‘symlinkfile2’? y
rm: remove symbolic link ‘symlinkfile3’? y

1a) 使用 rm 命令怎样移除符号链接目录

这像移除符号链接文件那样。使用下列命令移除符号链接目录。

# rm -i symlinkdir

rm: remove symbolic link ‘symlinkdir’? y

使用下列命令移除多个符号链接目录。

# rm -i symlinkdir1 symlinkdir2

rm: remove symbolic link ‘symlinkdir1’? y
rm: remove symbolic link ‘symlinkdir2’? y

如果你在结尾增加 /,这个符号链接目录将不会被删除。如果你加了,你将得到一个错误。

# rm -i symlinkdir/

rm: cannot remove ‘symlinkdir/’: Is a directory

你可以增加 -r 去处理上述问题。但如果你增加这个参数,它将会删除目标目录下的内容,并且它不会删除这个符号链接文件。(LCTT 译注:这可能不是你的原意。)

# rm -ri symlinkdir/

rm: descend into directory ‘symlinkdir/’? y
rm: remove regular file ‘symlinkdir/file4.txt’? y
rm: remove directory ‘symlinkdir/’? y
rm: cannot remove ‘symlinkdir/’: Not a directory

2) 使用 unlink 命令怎样移除符号链接

unlink 命令删除指定文件。它一次仅接受一个文件。

删除符号链接文件:

# unlink symlinkfile

删除符号链接目录:

# unlink symlinkdir2

如果你在结尾增加 /,你不能使用 unlink 命令删除符号链接目录。

# unlink symlinkdir3/

unlink: cannot unlink ‘symlinkdir3/’: Not a directory

via: https://www.2daygeek.com/remove-delete-symbolic-link-softlink-linux/

作者:Magesh Maruthamuthu 选题:lujun9972 译者:arrowfeng 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

当我们在命令行上工作时,您可能需要在文件之间创建链接。这时,您可以可以借助一个专用命令,ln。本教程中,我们将通过一些简单易理解的例子来讨论此工具的基础知识。在此之前,值得一提的是,本教程所有例子都已在 Ubuntu 16.04 上测试通过。

Linux ln 命令

正如你现在所了解的,ln 命令能够让您在文件之间创建链接。下面就是 ln 工具的语法(或者使用其他一些可行的语法)。

ln [OPTION]... [-T] TARGET LINK_NAME (第一种形式)
ln [OPTION]... TARGET (第二种形式)
ln [OPTION]... TARGET... DIRECTORY (第三种形式)
ln [OPTION]... -t DIRECTORY TARGET... (第四种形式)

下面是 ln 工具 man 文档描述的内容:

在第一种形式下,为目标位置(TARGET)创建一个叫 LINK\_NAME 的链接。在第二种形式下,为目标位置(TARGET)在当前目录下创建一个链接(LCTT 译注:创建的为同名链接)。在第三和第四种形式中,在 DIRECTORY 目录下为每一个目标位置(TARGET)创建链接。默认创建硬链接,符号链接需要 --symbolic 选项。默认创建的每一个创建的链接(新链接的名字)都不能已经存在。当创建硬链接时,目标位置(TARGET)文件必须存在;符号链接可以保存任意文本,如果之后解析,相对链接的解析与其父目录有关。

通过下面问答风格的例子,可能会给你更好的理解。但是在此之前,建议您先了解 硬链接和软链接的区别.

Q1. 如何使用 ln 命令创建硬链接?

这很简单,你只需要像下面使用 ln 命令:

ln [file] [hard-link-to-file]

例如:

ln test.txt test_hard_link.txt

如何使用 ln 命令创建硬链接

如此,您便可以看见一个已经创建好的,名为 test_hard_link.txt 的硬链接。

Q2. 如何使用 ln 命令创建软/符号链接?

使用 -s 命令行选项:

ln -s [file] [soft-link-to-file]

例如:

ln -s test.txt test_soft_link.txt

如何使用 ln 命令创建软/符号链接

test_soft_link.txt 文件就是一个软/符号链接,以天蓝色文本 标识

Q3. 如何使用 ln 命令删除既存的同名目标文件?

默认情况下,ln 不允许您在目标目录下创建已存在的链接。

ln 命令示例

然而,如果一定要这么做,您可以使用 -f 命令行选项覆盖此行为。

如何使用 ln 命令创建软/符号链接

提示:如果您想在此删除过程中有所交互,您可以使用 -i 选项。

Q4. 如何使用 ln 命令创建现有文件的同名备份?

如果您不想 ln 删除同名的现有文件,您可以为这些文件创建备份。使用 -b 即可实现此效果,以这种方式创建的备份文件,会在其文件名结尾处包含一个波浪号(~)。

如何使用 ln 命令创建现有文件的同名备份

Q5. 如何在当前目录以外的其它目录创建链接?

使用 -t 选项指定一个文件目录(除了当前目录)。比如:

ls test* | xargs ln -s -t /home/himanshu/Desktop/

上述命令会为(当前目录下的)所有 test* 文件创建链接,并放到桌面目录下。

总结

当然,尤其对于新手来说,ln 并不是日常必备命令。但是,这是一个有用的命令,因为你永远不知道它什么时候能够节省你一天的时间。对于这个命令,我们已经讨论了一些实用的选项,如果你已经完成了这些,可以查询 man 文档 来了解更多详情。


via: https://www.howtoforge.com/linux-ln-command/

作者:Himanshu Arora 译者:CYLeft 校对:Locez

本文由 LCTT 原创编译,Linux中国 荣誉推出

学习如何使用链接,通过从 Linux 文件系统多个位置来访问文件,可以让日常工作变得轻松。

 title=

在我为 opensource.com 写过的关于 Linux 文件系统方方面面的文章中,包括 Linux 的 EXT4 文件系统的历史、特性以及最佳实践在 Linux 中管理设备Linux 文件系统概览用户指南:逻辑卷管理,我曾简要的提到过 Linux 文件系统一个有趣的特性,它允许用户从多个位置来访问 Linux 文件目录树中的文件来简化一些任务。

Linux 文件系统中有两种 链接 link 硬链接 hard link 软链接 soft link 。虽然二者差别显著,但都用来解决相似的问题。它们都提供了对单个文件的多个目录项(引用)的访问,但实现却大为不同。链接的强大功能赋予了 Linux 文件系统灵活性,因为一切皆是文件

举个例子,我曾发现一些程序要求特定的版本库方可运行。 当用升级后的库替代旧库后,程序会崩溃,提示旧版本库缺失。通常,库名的唯一变化就是版本号。出于直觉,我仅仅给程序添加了一个新的库链接,并以旧库名称命名。我试着再次启动程序,运行良好。程序就是一个游戏,人人都明白,每个玩家都会尽力使游戏进行下去。

事实上,几乎所有的应用程序链接库都使用通用的命名规则,链接名称中包含了主版本号,链接所指向的文件的文件名中同样包含了小版本号。再比如,程序的一些必需文件为了迎合 Linux 文件系统规范,从一个目录移动到另一个目录中,系统为了向后兼容那些不能获取这些文件新位置的程序在旧的目录中存放了这些文件的链接。如果你对 /lib64 目录做一个长清单列表,你会发现很多这样的例子。

lrwxrwxrwx.  1 root root       36 Dec  8  2016 cracklib_dict.hwm -> ../../usr/share/cracklib/pw_dict.hwm 
lrwxrwxrwx.  1 root root       36 Dec  8  2016 cracklib_dict.pwd -> ../../usr/share/cracklib/pw_dict.pwd 
lrwxrwxrwx.  1 root root       36 Dec  8  2016 cracklib_dict.pwi -> ../../usr/share/cracklib/pw_dict.pwi
lrwxrwxrwx.  1 root root       27 Jun  9  2016 libaccountsservice.so.0 -> libaccountsservice.so.0.0.0 
-rwxr-xr-x.  1 root root   288456 Jun  9  2016 libaccountsservice.so.0.0.0 
lrwxrwxrwx   1 root root       15 May 17 11:47 libacl.so.1 -> libacl.so.1.1.0 
-rwxr-xr-x   1 root root    36472 May 17 11:47 libacl.so.1.1.0 
lrwxrwxrwx.  1 root root       15 Feb  4  2016 libaio.so.1 -> libaio.so.1.0.1 
-rwxr-xr-x.  1 root root     6224 Feb  4  2016 libaio.so.1.0.0 
-rwxr-xr-x.  1 root root     6224 Feb  4  2016 libaio.so.1.0.1 
lrwxrwxrwx.  1 root root       30 Jan 16 16:39 libakonadi-calendar.so.4 -> libakonadi-calendar.so.4.14.26 
-rwxr-xr-x.  1 root root   816160 Jan 16 16:39 libakonadi-calendar.so.4.14.26 
lrwxrwxrwx.  1 root root       29 Jan 16 16:39 libakonadi-contact.so.4 -> libakonadi-contact.so.4.14.26 

/lib64 目录下的一些链接

在上面展示的 /lib64 目录清单列表中,文件模式第一个字母 l (小写字母 l)表示这是一个软链接(又称符号链接)。

硬链接

Linux 的 EXT4 文件系统的历史、特性以及最佳实践一文中,我曾探讨过这样一个事实,每个文件都有一个包含该文件信息的 inode,包含了该文件的位置信息。上述文章中的图2展示了一个指向 inode 的单一目录项。每个文件都至少有一个目录项指向描述该文件信息的 inode ,目录项是一个硬链接,因此每个文件至少都有一个硬链接。

如下图 1 所示,多个目录项指向了同一 inode 。这些目录项都是硬链接。我曾在三个目录项中使用波浪线 (~) 的缩写,这是用户目录的惯例表示,因此在该例中波浪线等同于 /home/user 。值得注意的是,第四个目录项是一个完全不同的目录,/home/shared,可能是该计算机上用户的共享文件目录。

fig1directory_entries.png

图 1

硬链接被限制在一个单一的文件系统中。此处的“文件系统” 是指挂载在特定挂载点上的分区或逻辑卷,此例中是 /home。这是因为在每个文件系统中的 inode 号都是唯一的。而在不同的文件系统中,如 /var/opt,会有和 /home 中相同的 inode 号。

因为所有的硬链接都指向了包含文件元信息的单一 inode ,这些属性都是文件的一部分,像所属关系、权限、到该 inode 的硬链接数目,对每个硬链接来说这些特性没有什么不同的。这是一个文件所具有的一组属性。唯一能区分这些文件的是包含在 inode 信息中的文件名。链接到同一目录中的单一文件/ inode 的硬链接必须拥有不同的文件名,这是基于同一目录下不能存在重复的文件名的事实的。

文件的硬链接数目可通过 ls -l 来查看,如果你想查看实际节点号,可使用 ls -li 命令。

符号(软)链接

硬链接和软链接(也称为 符号链接 symlink )的区别在于,硬链接直接指向属于该文件的 inode ,而软链接直接指向一个目录项,即指向一个硬链接。因为软链接指向的是一个文件的硬链接而非该文件的 inode ,所以它们并不依赖于 inode 号,这使得它们能跨越不同的文件系统、分区和逻辑卷起作用。

软链接的缺点是,一旦它所指向的硬链接被删除或重命名后,该软链接就失效了。软链接虽然还在,但所指向的硬链接已不存在。所幸的是,ls 命令能以红底白字的方式在其列表中高亮显示失效的软链接。

实验项目: 链接实验

我认为最容易理解链接用法及其差异的方法是动手搭建一个项目。这个项目应以非超级用户的身份在一个空目录下进行。我创建了 ~/temp 目录做这个实验,你也可以这么做。这么做可为项目创建一个安全的环境且提供一个新的空目录让程序运作,如此以来这儿仅存放和程序有关的文件。

初始工作

首先,在你要进行实验的目录下为该项目中的任务创建一个临时目录,确保当前工作目录(PWD)是你的主目录,然后键入下列命令。

mkdir temp

使用这个命令将当前工作目录切换到 ~/temp

cd temp

实验开始,我们需要创建一个能够链接到的文件,下列命令可完成该工作并向其填充内容。

du -h > main.file.txt

使用 ls -l 长列表命名确认文件正确地创建了。运行结果应类似于我的。注意文件大小只有 7 字节,但你的可能会有 1~2 字节的变动。

[dboth@david temp]$ ls -l 
total 4 
-rw-rw-r-- 1 dboth dboth 7 Jun 13 07:34 main.file.txt

在列表中,文件模式串后的数字 1 代表存在于该文件上的硬链接数。现在应该是 1 ,因为我们还没有为这个测试文件建立任何硬链接。

对硬链接进行实验

硬链接创建一个指向同一 inode 的新目录项,当为文件添加一个硬链接时,你会看到链接数目的增加。确保当前工作目录仍为 ~/temp。创建一个指向 main.file.txt 的硬链接,然后查看该目录下文件列表。

[dboth@david temp]$ ln main.file.txt link1.file.txt 
[dboth@david temp]$ ls -l 
total 8 
-rw-rw-r-- 2 dboth dboth 7 Jun 13 07:34 link1.file.txt 
-rw-rw-r-- 2 dboth dboth 7 Jun 13 07:34 main.file.txt

目录中两个文件都有两个链接且大小相同,时间戳也一样。这就是有一个 inode 和两个硬链接(即该文件的目录项)的一个文件。再建立一个该文件的硬链接,并列出目录清单内容。你可以建立硬链接: link1.file.txtmain.file.txt

[dboth@david temp]$ ln link1.file.txt link2.file.txt ; ls -l
total 16 
-rw-rw-r-- 3 dboth dboth 7 Jun 13 07:34 link1.file.txt 
-rw-rw-r-- 3 dboth dboth 7 Jun 13 07:34 link2.file.txt 
-rw-rw-r-- 3 dboth dboth 7 Jun 13 07:34 main.file.txt

注意,该目录下的每个硬链接必须使用不同的名称,因为同一目录下的两个文件不能拥有相同的文件名。试着创建一个和现存链接名称相同的硬链接。

[dboth@david temp]$ ln main.file.txt link2.file.txt 
ln: failed to create hard link 'link2.file.txt': File exists

显然不行,因为 link2.file.txt 已经存在。目前为止我们只在同一目录下创建硬链接,接着在临时目录的父目录(你的主目录)中创建一个链接。

[dboth@david temp]$ ln main.file.txt ../main.file.txt ; ls -l ../main*
-rw-rw-r--    4 dboth dboth     7 Jun 13 07:34 main.file.txt

上面的 ls 命令显示 main.file.txt 文件确实存在于主目录中,且与该文件在 temp 目录中的名称一致。当然它们不是不同的文件,它们是同一文件的两个链接,指向了同一文件的目录项。为了帮助说明下一点,在 temp 目录中添加一个非链接文件。

[dboth@david temp]$ touch unlinked.file ; ls -l
total 12
-rw-rw-r-- 4 dboth dboth 7 Jun 13 07:34 link1.file.txt
-rw-rw-r-- 4 dboth dboth 7 Jun 13 07:34 link2.file.txt
-rw-rw-r-- 4 dboth dboth 7 Jun 13 07:34 main.file.txt
-rw-rw-r-- 1 dboth dboth 0 Jun 14 08:18 unlinked.file

使用 ls 命令的 i 选项查看 inode 的硬链接号和新创建文件的硬链接号。

[dboth@david temp]$ ls -li
total 12
657024 -rw-rw-r-- 4 dboth dboth 7 Jun 13 07:34 link1.file.txt
657024 -rw-rw-r-- 4 dboth dboth 7 Jun 13 07:34 link2.file.txt
657024 -rw-rw-r-- 4 dboth dboth 7 Jun 13 07:34 main.file.txt
657863 -rw-rw-r-- 1 dboth dboth 0 Jun 14 08:18 unlinked.file

注意上面文件模式左边的数字 657024 ,这是三个硬链接文件所指的同一文件的 inode 号,你也可以使用 i 选项查看主目录中所创建的链接的节点号,和该值相同。而那个只有一个链接的 inode 号和其他的不同,在你的系统上看到的 inode 号或许不同于本文中的。

接着改变其中一个硬链接文件的大小。

[dboth@david temp]$ df -h > link2.file.txt ; ls -li
total 12
657024 -rw-rw-r-- 4 dboth dboth 1157 Jun 14 14:14 link1.file.txt
657024 -rw-rw-r-- 4 dboth dboth 1157 Jun 14 14:14 link2.file.txt
657024 -rw-rw-r-- 4 dboth dboth 1157 Jun 14 14:14 main.file.txt
657863 -rw-rw-r-- 1 dboth dboth    0 Jun 14 08:18 unlinked.file

现在所有的硬链接文件大小都比原来大了,因为多个目录项都链接着同一文件。

下个实验在我的电脑上会出现这样的结果,是因为我的 /tmp 目录在一个独立的逻辑卷上。如果你有单独的逻辑卷或文件系统在不同的分区上(如果未使用逻辑卷),确定你是否能访问那个分区或逻辑卷,如果不能,你可以在电脑上挂载一个 U 盘,如果上述方式适合你,你可以进行这个实验。

试着在 /tmp 目录中建立一个 ~/temp 目录下文件的链接(或你的文件系统所在的位置)。

[dboth@david temp]$ ln link2.file.txt /tmp/link3.file.txt
ln: failed to create hard link '/tmp/link3.file.txt' => 'link2.file.txt': 
Invalid cross-device link

为什么会出现这个错误呢? 原因是每一个单独的可挂载文件系统都有一套自己的 inode 号。简单的通过 inode 号来跨越整个 Linux 文件系统结构引用一个文件会使系统困惑,因为相同的节点号会存在于每个已挂载的文件系统中。

有时你可能会想找到一个 inode 的所有硬链接。你可以使用 ls -li 命令。然后使用 find 命令找到所有硬链接的节点号。

[dboth@david temp]$ find . -inum 657024 
./main.file.txt
./link1.file.txt
./link2.file.txt

注意 find 命令不能找到所属该节点的四个硬链接,因为我们在 ~/temp 目录中查找。 find 命令仅在当前工作目录及其子目录中查找文件。要找到所有的硬链接,我们可以使用下列命令,指定你的主目录作为起始查找条件。

[dboth@david temp]$ find ~ -samefile main.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 选项而不是指定文件的节点号。这个效果和使用 inode 号一样且更容易,如果你知道其中一个硬链接名称的话。

对软链接进行实验

如你刚才看到的,不能跨越文件系统边界创建硬链接,即在逻辑卷或文件系统中从一个文件系统到另一个文件系统。软链接给出了这个问题的解决方案。虽然它们可以达到相同的目的,但它们是非常不同的,知道这些差异是很重要的。

让我们在 ~/temp 目录中创建一个符号链接来开始我们的探索。

[dboth@david temp]$ ln -s link2.file.txt link3.file.txt ; ls -li
total 12
657024 -rw-rw-r-- 4 dboth dboth 1157 Jun 14 14:14 link1.file.txt
657024 -rw-rw-r-- 4 dboth dboth 1157 Jun 14 14:14 link2.file.txt
658270 lrwxrwxrwx 1 dboth dboth   14 Jun 14 15:21 link3.file.txt -> 
link2.file.txt
657024 -rw-rw-r-- 4 dboth dboth 1157 Jun 14 14:14 main.file.txt
657863 -rw-rw-r-- 1 dboth dboth    0 Jun 14 08:18 unlinked.file

拥有节点号 657024 的那些硬链接没有变化,且硬链接的数目也没有变化。新创建的符号链接有不同的 inode 号 658270。 名为 link3.file.txt 的软链接指向了 link2.file.txt 文件。使用 cat 命令查看 link3.file.txt 文件的内容。符号链接的 inode 信息以字母 l (小写字母 l)开头,意味着这个文件实际是个符号链接。

上例中软链接文件 link3.file.txt 的大小只有 14 字节。这是文本内容 link3.file.txt 的大小,即该目录项的实际内容。目录项 link3.file.txt 并不指向一个 inode ;它指向了另一个目录项,这在跨越文件系统建立链接时很有帮助。现在试着创建一个软链接,之前在 /tmp 目录中尝试过的。

[dboth@david temp]$ ln -s /home/dboth/temp/link2.file.txt 
/tmp/link3.file.txt ; ls -l /tmp/link*
lrwxrwxrwx 1 dboth dboth 31 Jun 14 21:53 /tmp/link3.file.txt -> 
/home/dboth/temp/link2.file.txt

删除链接

当你删除硬链接或硬链接所指的文件时,需要考虑一些问题。

首先,让我们删除硬链接文件 main.file.txt。注意指向 inode 的每个目录项就是一个硬链接。

[dboth@david temp]$ rm main.file.txt ; ls -li
total 8
657024 -rw-rw-r-- 3 dboth dboth 1157 Jun 14 14:14 link1.file.txt
657024 -rw-rw-r-- 3 dboth dboth 1157 Jun 14 14:14 link2.file.txt
658270 lrwxrwxrwx 1 dboth dboth   14 Jun 14 15:21 link3.file.txt -> 
link2.file.txt
657863 -rw-rw-r-- 1 dboth dboth    0 Jun 14 08:18 unlinked.file

main.file.txt 是该文件被创建时所创建的第一个硬链接。现在删除它,仍然保留着原始文件和硬盘上的数据以及所有剩余的硬链接。要删除原始文件,你必须删除它的所有硬链接。

现在删除 link2.file.txt 硬链接文件。

[dboth@david temp]$ rm link2.file.txt ; ls -li 
total 8 
657024 -rw-rw-r-- 3 dboth dboth 1157 Jun 14 14:14 link1.file.txt 
658270 lrwxrwxrwx 1 dboth dboth   14 Jun 14 15:21 link3.file.txt -> 
link2.file.txt 
657024 -rw-rw-r-- 3 dboth dboth 1157 Jun 14 14:14 main.file.txt 
657863 -rw-rw-r-- 1 dboth dboth    0 Jun 14 08:18 unlinked.file

注意软链接的变化。删除软链接所指的硬链接会使该软链接失效。在我的系统中,断开的链接用颜色高亮显示,目标的硬链接会闪烁显示。如果需要修复这个损坏的软链接,你需要在同一目录下建立一个和旧链接相同名字的硬链接,只要不是所有硬链接都已删除就行。您还可以重新创建链接本身,链接保持相同的名称,但指向剩余的硬链接中的一个。当然如果软链接不再需要,可以使用 rm 命令删除它们。

unlink 命令在删除文件和链接时也有用。它非常简单且没有选项,就像 rm 命令一样。然而,它更准确地反映了删除的基本过程,因为它删除了目录项与被删除文件的链接。

写在最后

我用过这两种类型的链接很长一段时间后,我开始了解它们的能力和特质。我为我所教的 Linux 课程编写了一个实验室项目,以充分理解链接是如何工作的,并且我希望增进你的理解。

(题图: Paul Lewin,Opensource.com 修改。 CC BY-SA 2.0


作者简介:

戴维.布斯 - 戴维.布斯是 Linux 和开源倡导者,居住在北卡罗莱纳的罗列 。他在 IT 行业工作了四十年,为 IBM 工作了 20 多年的 OS/2。在 IBM 时,他在 1981 年编写了最初的 IBM PC 的第一个培训课程。他为 RedHat 教授过 RHCE 班,并曾在 MCI Worldcom、思科和北卡罗莱纳州工作。他已经用 Linux 和开源软件工作将近 20 年了。


via: https://opensource.com/article/17/6/linking-linux-filesystem

作者:David Both 译者:yongshouzhang 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出