最近我在一次工作面试中被问到这个问题。老实说,我知道符号链接的行为方式以及如何创建符号链接,但不了解硬链接的使用以及它与符号链接的区别。
在文件系统之下,文件由 inode 表示。 (或者是多个inode?不确定。)
文件系统中的文件基本上是指向 inode 的链接。那么,硬链接只会创建另一个文件,其中包含指向同一底层 inode 的链接。
当您删除一个文件时,它会删除一个指向底层 inode 的链接。仅当所有指向该 inode 的链接都已删除时,该 inode 才会被删除(或可删除/可覆盖)。
符号链接是指向文件系统中另一个名称的链接。
建立硬链接后,链接将指向 inode。删除、重命名或移动原始文件不会影响硬链接,因为它链接到底层 inode。对 inode 上数据的任何更改都会反映在引用该 inode 的所有文件中。
注意:硬链接仅在同一文件系统内有效。符号链接可以跨越文件系统,因为它们只是另一个文件的名称。
一些可能有帮助的例子。
创建两个包含数据的文件:
$ printf Cat > foo
$ printf Dog > bar
创建一个硬链接和软链接(又名符号链接):
$ ln foo foo-hard
$ ln -s bar bar-soft
通过增加大小以长格式列出目录内容:
ls -lrS
lrwxr-xr-x 1 user staff 3 3 Apr 15:25 bar-soft -> bar
-rw-r--r-- 2 user staff 4 3 Apr 15:25 foo-hard
-rw-r--r-- 2 user staff 4 3 Apr 15:25 foo
-rw-r--r-- 1 user staff 4 3 Apr 15:25 bar
这告诉我们
第一列:软链接和硬链接的文件模式不同软链接:lrwxr-xr-x 文件类型:l = 符号链接所有者权限:rwx = 可读、可写、可执行组权限:rx = 可读、不可写、可执行其他权限: rx = 可读,不可写,可执行硬链接:-rw-r--r-- 文件类型:- = 常规文件所有者权限:rw- = 可读,可写,不可执行组权限:r-- = 可读,不可写, 不可执行其他权限:r-- = 可读,不可写,不可执行
软链接:lrwxr-xr-x 文件类型:l = 符号链接所有者权限:rwx = 可读、可写、可执行 组权限:rx = 可读、不可写、可执行 其他权限:rx = 可读、不可写、可执行
文件类型:l = 符号链接
所有者权限:rwx = 可读、可写、可执行
组权限:rx = 可读,不可写,可执行
其他权限:rx = 可读,不可写,可执行
硬链接:-rw-r--r-- 文件类型:- = 常规文件所有者权限:rw- = 可读、可写、不可执行组权限:r-- = 可读、不可写、不可执行其他权限:r-- = 可读、不可写、不可执行
文件类型:- = 常规文件
所有者权限:rw- = 可读、可写、不可执行
组权限:r-- = 可读、不可写、不可执行
其他权限:r-- = 可读、不可写、不可执行
第二列:硬链接文件的链接数较高
第 5 列:软链接的大小更小,因为它是参考而不是副本
最后一列:符号链接通过 -> 显示链接到的文件
更改 foo 的文件名不会影响 foo-hard:
$ mv foo foo-new
$ cat foo-hard
Cat
更改 foo 的内容会反映在 foo-hard 中:
$ printf Dog >> foo
$ cat foo-hard
CatDog
像 foo-hard 这样的硬链接指向文件的 inode 和内容。
对于 bar-soft 之类的软链接,情况并非如此:
$ mv bar bar-new
$ ls bar-soft
bar-soft
$ cat bar-soft
cat: bar-soft: No such file or directory
找不到文件的内容,因为软链接指向已更改的名称,而不是内容。
同样,如果 foo
被删除,foo-hard
仍然保留内容;如果删除 bar
,则 bar-soft
只是指向不存在文件的链接。
touch blah1; touch blah2
可以缩短为 touch blah1 blah2
俗话说,一图胜千言。这是我将其可视化的方式:
https://i.stack.imgur.com/ka2ab.jpg
这是我们如何得到这张照片的:
在文件系统中创建一个名称 myfile.txt 指向一个新的 inode(其中包含文件的元数据并指向包含其内容的数据块,即文本“Hello, World!”:$ echo 'Hello , World!' > myfile.txt 创建硬链接 my-hard-link 到文件 myfile.txt,意思是“创建一个应该指向 myfile.txt 指向的同一个 inode 的文件”: $ ln myfile.txt my-hard-link 创建指向文件 myfile.txt 的软链接 my-soft-link,意思是“创建一个应该指向文件 myfile.txt 的文件”: $ ln -s myfile.txt my-soft-link
看看如果 myfile.txt
被删除(或移动)会发生什么:my-hard-link
仍然指向相同的内容,因此不受影响,而 my-soft-link
现在不指向任何内容。其他答案讨论了每种方法的优缺点。
myfile.txt
引用的同一个 inode)。对于软链接,它的引用不是 inode(包含数据),而是它的引用是 myfile.txt
的文件系统路径(例如 /home/Documents/myfile.txt
)
当原始文件被移动时,硬链接很有用。例如,将文件从 /bin 移动到 /usr/bin 或 /usr/local/bin。 /bin 中文件的任何符号链接都会因此而被破坏,但是硬链接是直接指向文件 inode 的链接,不会在意。
硬链接可能占用更少的磁盘空间,因为它们只占用一个目录条目,而符号链接需要自己的 inode 来存储它指向的名称。
硬链接也需要更少的时间来解决 - 符号链接可以指向符号链接目录中的其他符号链接。其中一些可能位于 NFS 或其他高延迟文件系统上,因此可能会导致网络流量无法解析。硬链接总是在同一个文件系统上,总是在一次查找中被解析,并且从不涉及网络延迟(如果它是 NFS 文件系统上的硬链接,NFS 服务器会进行解析,并且它对客户端系统)。有时这很重要。不适合我,但我可以想象这可能很重要的高性能系统。
我还认为 mmap(2) 甚至 open(2) 之类的东西使用与硬链接相同的功能来保持文件的 inode 处于活动状态,这样即使文件被 unlink(2)ed,inode 仍然允许进程继续访问,只有在进程关闭后,文件才会真正消失。这允许更安全的临时文件(如果您可以以原子方式打开和取消链接,可能有一个我不记得的 POSIX API,那么您确实有一个安全的临时文件)您可以在其中读/写您的数据,任何人都无法访问它。好吧,在 /proc 让每个人都能够查看文件描述符之前确实如此,但那是另一回事了。
说到这一点,恢复在进程 A 中打开但在文件系统上未链接的文件围绕使用硬链接重新创建 inode 链接,因此当打开文件的进程关闭或消失时文件不会消失。
软链接:
soft 或 symbolic 更像是原始文件的快捷方式....如果您删除原始文件,则快捷方式将失败,如果您只删除快捷方式,则原始文件不会发生任何事情。
软链接语法:ln -s Pathof_Target_file link
输出: link -> ./Target_file
证明: readlink link
同样在 ls -l link
输出中,您会看到 lrwxrwxrwx
中的第一个字母为 l,这表明该文件是软链接。
删除链接: unlink link
注意:如果您愿意,即使将软链接从当前目录移到其他地方,您的软链接也可以工作。确保在创建软链接时提供绝对路径而不是相对路径。即(从 /root/user/Target_file 而不是 ./Target_file 开始)
硬链接:
硬链接更多的是镜像副本或同一文件的多个路径。对文件 1 做一些事情,它出现在文件 2 中。删除一个仍然可以保持另一个。
仅当所有(硬)链接或(同一文件)inode 的所有路径都已删除时,inode(或文件)才会被删除。
建立硬链接后,该链接具有原始文件的 inode。删除重命名或移动原始文件不会影响硬链接,因为它链接到底层 inode。对 inode 上数据的任何更改都会反映在引用该 inode 的所有文件中。
硬链接语法:ln Target_file link
输出:将使用与 Targetfile 相同的 inode 编号创建一个名为 link 的文件。
证明: ls -i link Target_file
(检查他们的 inode)
删除链接: rm -f link
(像普通文件一样删除链接)
注意:符号链接可以跨越文件系统,因为它们只是另一个文件的名称。而硬链接仅在同一文件系统中有效。
符号链接有一些硬链接缺失的功能:
硬链接指向文件内容。而软链接指向文件名。
而硬链接的大小是内容的大小,而软链接的大小是文件名大小。
硬链接共享相同的 inode。软链接没有。
硬链接不能跨文件系统。软链接可以。
您立即知道符号链接指向的位置,而使用硬链接,您需要探索整个文件系统以找到共享相同 inode 的文件。 # find / -inum 517333 /home/bobbin/sync.sh /root/synchro
硬链接不能指向目录。
硬链接有两个限制:
目录不能硬链接。 Linux 不允许这样做来维护目录的非循环树结构。
不能跨文件系统创建硬链接。这两个文件必须在同一个文件系统上,因为不同的文件系统有不同的独立 inode 表(不同文件系统上的两个文件,但具有相同的 inode 号会不同)。
查看硬链接和符号链接之间区别的一种简单方法是通过一个简单的示例。文件的硬链接将指向文件的存储位置,或该文件的 inode。符号链接将指向实际文件本身。
因此,如果我们有一个名为“a”的文件并创建一个硬链接“b”和一个符号链接“c”,它们都引用文件“a”:
echo "111" > a
ln a b
ln -s a c
“a”、“b”和“c”的输出将是:
cat a --> 111
cat b --> 111
cat c --> 111
现在让我们删除文件“a”,看看“a”、“b”和“c”的输出会发生什么:
rm a
cat a --> No such file or directory
cat b --> 111
cat c --> No such file or directory
所以发生了什么事?
因为文件“c”指向文件“a”本身,如果文件“a”被删除,那么文件“c”将没有可指向的东西,实际上它也被删除了。
但是,文件“b”指向文件“a”的存储位置或 inode。因此,如果文件“a”被删除,那么它将不再指向 inode,但因为文件“b”这样做,inode 将继续存储属于“a”的任何内容,直到不再有硬链接指向它为止。
符号链接链接到路径名。这可以在系统文件树中的任何位置,甚至在创建链接时也不必存在。目标路径可以是相对的或绝对的。
硬链接是指向 inode 的附加指针,这意味着它们只能存在于与目标相同的卷上。文件的附加硬链接与用于引用文件的“原始”名称无法区分。
我会把你指向维基百科:
符号链接
硬链接
几点:
与硬链接不同,符号链接可以跨文件系统(大部分时间)。
符号链接可以指向目录。
硬链接指向一个文件,使您能够使用多个名称引用同一个文件。
只要至少有一个链接,数据仍然可用。
进行增量备份时,硬链接非常有用。例如,参见 rsnapshot。这个想法是使用硬链接进行复制:
将备份编号 n 复制到 n + 1
将备份 n - 1 复制到 n
...
将备份 0 复制到备份 1
使用任何更改的文件更新备份 0。
除了您所做的任何更改之外,新备份不会占用任何额外空间,因为所有增量备份将指向未更改文件的同一组 inode。
https://i.stack.imgur.com/uNXQS.png
这张图片可以很容易地解释硬链接与软链接。
来自 MSDN,
符号链接
符号链接是指向另一个文件系统对象的文件系统对象。被指向的对象称为目标。符号链接对用户是透明的;链接显示为普通文件或目录,用户或应用程序可以以完全相同的方式对其进行操作。符号链接旨在帮助迁移和应用程序与 UNIX 操作系统的兼容性。 Microsoft 已实现其符号链接,使其功能与 UNIX 链接一样。符号链接可以是绝对链接或相对链接。绝对链接是指定路径名各部分的链接;相对链接是相对于相对链接说明符在指定路径中的位置确定的
绝对符号链接的示例
X: "C:\alpha\beta\absLink\gamma\file"
Link: "absLink" maps to "\\machineB\share"
Modified Path: "\\machineB\share\gamma\file"
相对符号链接的示例
X: C:\alpha\beta\link\gamma\file
Link: "link" maps to "..\..\theta"
Modified Path: "C:\alpha\beta\..\..\theta\gamma\file"
Final Path: "C:\theta\gamma\file"
硬链接
硬链接是文件的文件系统表示,多个路径通过该文件引用同一卷中的单个文件。
要在 Windows 中创建硬链接,请导航到要创建链接的位置并输入以下命令:
mklink /H Link_name target_path
请注意,您可以按任何顺序删除硬链接,而不管它们的创建顺序如何。此外,硬链接无法创建时
引用位于不同的本地驱动器中
参考包括网络驱动器。换句话说,其中一个参考是网络驱动器
要创建的硬链接与目标在同一路径中
结
NTFS 支持另一种称为联结的链接类型。 MSDN 定义如下:
联结(也称为软链接)与硬链接的不同之处在于它引用的存储对象是单独的目录,并且联结可以链接位于同一台计算机上不同本地卷上的目录。否则,结点的操作与硬链接相同。
硬链接部分和连接部分中的粗体部分显示了两者之间的基本区别。
在 windows 中创建连接的命令,导航到要创建链接的位置,然后输入:
mklink /J link_name target_path
我补充尼克的问题:硬链接什么时候有用或必要?我想到的唯一应用程序,其中符号链接不能完成这项工作,是在 chroot 环境中提供系统文件的副本。
简单来说,硬链接:就是给一个文件添加一个新的名字,也就是说,一个文件可以同时有多个名字,所有名字都是一样的,没有一个首选,硬链接不是复制所有内容文件并制作新文件不是那样,它只是创建一个已知的替代名称..
符号链接(symlink):是指向另一个文件的文件指针,如果符号链接指向一个现有文件,该文件后来被删除,则符号链接继续指向相同的文件名,即使该名称不再命名任何文件。
还:
硬链接的读取性能优于符号链接(微性能)符号链接可以复制,版本控制,..等。换句话说,它们是一个实际的文件。另一方面,硬链接的级别略低,您会发现与符号链接相比,提供将硬链接作为硬链接而不是普通文件处理的方法的工具较少
您认为的普通“文件”实际上是两个独立的东西:文件的数据和目录条目。为文件创建硬链接时,实际上是创建了第二个目录条目,它引用了相同的数据。两个目录条目具有完全相同的功能;每一个都可以用来打开文件来读取它。因此,您实际上并没有“一个文件加上一个硬链接”,而是“具有两个目录条目的文件数据”。您认为删除文件实际上会删除目录条目,当数据的最后一个目录条目被删除时,数据本身也会被删除。对于只有一个目录条目的普通文件,删除目录条目会像往常一样删除数据。 (打开文件时,操作系统会创建一个指向该文件的临时链接,因此即使您删除所有目录条目,数据也会保留,但在您关闭文件后会立即消失)。
例如,创建一个文件 A.txt,一个硬链接 B.txt,并删除 A.txt。创建 A.txt 时,会创建一些数据和目录条目 A.txt。创建硬链接时,会创建另一个目录条目 B.txt,指向完全相同的数据。当您删除 A.txt 时,您仍然拥有所有数据和单个目录条目 B.txt,就好像您首先创建了一个文件 B.txt。
软链接只是一个(几乎)普通文件,只是它不包含数据,而是另一个目录条目的路径。如果您删除软链接引用的文件,则软链接将包含不再指向目录条目的路径;它被打破。如果删除软链接,就像删除任何其他文件一样,它指向的文件不受影响。
目录条目是链接结构:
struct dentry{
ino_t ino;
char name[256];
}
ino是inode的个数,name是文件名,inode结构可能是这样的:
struct inode{
link_t nlink;
...
}
例如,您创建一个文件 /1,目录条目可能如下:
struct dentry{
ino_t ino; /* such as 15 */
char name[256]; /* "1" */
}
inode 结构可能像:
struct inode{ /* inode number 15 */
link_t nlink; /* nlink = 1 */
...
}
然后你创建一个硬链接(可能是/100),目录条目可能像:
struct dentry{
ino_t ino; /* 15 */
char name[256]; /* 100 */
}
inode 结构可能像:
struct inode{ /* inode numebr 15 */
link_t nlink; /* nlink = 2 */
...
}
然后你创建一个到文件 1 的符号链接(可能是 /200),目录条目可能像:
struct dentry{
ino_t ino; /* such as 16 */
char name[256]; /* "200" */
}
inode 结构可能像:
struct inode{ /* inode number 15 */
link_t nlink; /* nlink = 2 */
...
}
struct inode{ /* inode number 16 */
link_t nlink; /* nlink = 1 */
...
} /* the data of inode 16 maybe /1 or 1 */
我的两分钱使用:
软链接可用于缩短长路径名,即:
ln -s /long/folder/name/on/long/path/file.txt /short/file.txt
对 /short/file.txt
所做的更改将应用于原始文件。
硬链接可用于移动大文件:
$ ls -lh /myapp/dev/
total 10G
-rw-r--r-- 2 root root 10G May 22 12:09 application.bin
ln /myapp/dev/application.bin /myapp/prd/application.bin
即时复制到不同的文件夹,并且可以移动或删除原始文件(在 /myapp/dev
上),而无需触摸 /myapp/prd
上的文件
加上上面所有的答案,找到硬链接和软链接文件的区别可以理解如下:
我的当前目录中有一个文件 f6
,还有一个名为 t2
的目录。
名为 f1
和 ./t2/f2
的文件是指向 f6
的符号链接。
名为 f7
和 ./t2/f8
的文件是 f6
的硬链接。
要找到软链接和硬链接,我们可以使用:
$ find -L . -samefile f6
> ./f1
> ./f6
> ./f7
> ./t2/f2
> ./t2/f8
要仅查找硬链接,我们可以使用:
$ find . -xdev -samefile f6
> ./f6
> ./f7
> ./t2/f8
由于可以在同一个文件系统上创建硬链接,我们可以在同一个文件系统/挂载点中搜索所有未使用 -L
选项(使用 -xdev
选项)的硬链接。它将不必要的搜索保存到不同的挂载点。
所以搜索硬链接比搜索软链接要快一些(如果我错了或不清楚,请纠正)。
此答案适用于 Web 开发人员🙃:
硬链接:就像将不同的域名指向同一个主机
* abc.com and def.com -> points to the IP 1.2.3.4
* abc.com and def.com -> files in linux
* IP -> inode in linux
* By deleting the domain abc.com users still access your website through def.com or vice versa
* Mutation through abc.com will affect def.com and vice verca
符号链接:将一个域重定向到另一个域
* accessing abc.com will redirect to def.com as you've accessed def.com directly
* removing the def.com domain will break the link abc.com
符号链接以类似于硬链接的方式为文件提供另一个名称。但是即使有剩余的符号链接,也可以删除文件。
我刚刚找到了一种简单的方法来理解常见场景中的硬链接,即软件安装。
有一天,我下载了一个软件到文件夹 Downloads
进行安装。在我执行 sudo make install
之后,一些可执行文件cp
被编入本地 bin 文件夹。在这里,cp
创建硬链接。我对这个软件很满意,但很快意识到 Downloads
从长远来看并不是一个好地方。所以我mv
将软件文件夹添加到 source
目录。好吧,我仍然可以像以前一样运行该软件,而不必担心任何目标链接的事情,就像在 Windows 中一样。这意味着 硬链接 直接查找 inode 和周围的其他文件。
在这个答案中,当我说一个文件时,我的意思是内存中的位置
保存的所有数据都使用称为 inodes 的数据结构存储在内存中。每个 inode 都有一个 inode 编号。inode 编号用于访问 inode。文件的所有硬链接可能具有不同的名称,但共享相同的 inode 编号。由于所有硬链接都具有相同的 inode 编号(反过来访问相同的 inode),它们都指向相同的物理内存。
符号链接是一种特殊的文件。因为它也是一个文件,所以它会有一个文件名和一个 inode 编号。如上所述,inode 编号访问一个指向数据的 inode。现在,符号链接的特殊之处在于符号链接中的 inode 编号访问指向另一个文件的“路径”的那些 inode。更具体地说,符号链接中的 inode 编号访问指向另一个硬链接的那些 inode。
当我们在 GUI 中移动、复制、删除文件时,我们正在使用文件的硬链接而不是物理内存。当我们删除文件时,我们正在删除文件的硬链接。我们不会清除物理内存。如果文件的所有硬链接都被删除,那么将无法访问存储的数据,尽管它可能仍然存在于内存中
我刚刚找到了一种简单的方法来理解常见场景中的硬链接,即软件安装。
有一天,我下载了一个软件到文件夹 Downloads 进行安装。在我执行 sudo make install 之后,一些可执行文件被保存到本地 bin 文件夹中。在这里, cp 创建硬链接。我对这个软件很满意,但很快意识到从长远来看,下载并不是一个好地方。所以我将软件文件夹移动到源目录。好吧,我仍然可以像以前一样运行该软件,而不必担心任何目标链接的事情,就像在 Windows 中一样。这意味着硬链接直接查找 inode 和周围的其他文件。
硬链接是 unix,就像它在 unix 和 linux 中是旧的一样,但是符号链接在 linux 中是新的。
硬链接 inode 与原始文件 inode 相同。但是 symbolik 链接 inode 与原始文件 inode 不同。
以字节为单位的硬链接文件大小与以字节为单位的原始文件大小相同。但是以字节为单位的符号链接文件大小与以字节为单位的原始文件大小不同。符号链接文件大小小于原始文件大小。
硬链接是原始文件的镜像副本。符号链接或软链接就像 Windows 中的快捷方式。
如果您删除原始文件,硬链接将保留其文件,您可以看到硬链接文件内容。在符号链接中,如果删除原始文件,其符号链接将断开,符号链接仍然存在,但无法显示符号链接内容。
符号链接是新的,它有很多功能,但硬链接是旧的,这就是为什么它的功能较少。
让我们使用终端制作一些硬链接和符号链接:echo "why so Serious" > file.txt
硬链接:ln file.txt file_hard
符号链接:ln -s file.txt file_sym
让我们看看 inode 的内容:ls -li
readlink -f <fileName>
将按照符号链指向真实文件。