最近我在一次工作面试中被问到这个问题。我诚实地说,我知道符号链接的行为和如何创建一个,但不了解硬链接的使用,以及它与符号链接的区别。
在文件系统下面,文件由inode表示。(或者是多个索引节点?不确定。)
文件系统中的文件基本上是一个到inode的链接。 因此,硬链接只是创建另一个文件,该文件具有指向相同底层inode的链接。
当您删除一个文件时,它会删除到底层inode的一个链接。只有当到inode的所有链接都被删除时,inode才会被删除(或可删除/可覆盖)。
符号链接是指向文件系统中另一个名称的链接。
一旦建立了硬链接,链接就指向inode。删除、重命名或移动原始文件不会影响硬链接,因为它链接到底层inode。对inode上数据的任何更改都反映在引用该inode的所有文件中。
注意:硬链接只在同一个文件系统内有效。符号链接可以跨文件系统,因为它们只是另一个文件的名称。
符号链接链接到路径名。它可以在系统文件树中的任何位置,甚至在创建链接时不需要存在。目标路径可以是相对路径,也可以是绝对路径。
硬链接是指向inode的附加指针,这意味着它们只能存在于与目标相同的卷上。到文件的附加硬链接与用于引用文件的“原始”名称难以区分。
我推荐你们去维基百科:
符号链接 硬链接
以下几点:
与硬链接不同,符号链接可以跨文件系统(大多数情况下)。 符号链接可以指向目录。 硬链接指向一个文件,并允许您使用多个名称引用同一个文件。 只要至少有一个链接,数据就仍然可用。
当原始文件被移动时,硬链接非常有用。例如,将文件从/bin移动到/usr/bin或/usr/local/bin。到/bin中文件的任何符号链接都将被破坏,但是硬链接(直接到文件的inode的链接)不会关心。
硬链接可能占用更少的磁盘空间,因为它们只占用一个目录条目,而符号链接需要自己的inode来存储它所指向的名称。
Hard links also take less time to resolve - symlinks can point to other symlinks that are in symlinked directories. And some of these could be on NFS or other high-latency file systems, and so could result in network traffic to resolve. Hard links, being always on the same file system, are always resolved in a single look-up, and never involve network latency (if it's a hardlink on an NFS filesystem, the NFS server would do the resolution, and it would be invisible to the client system). Sometimes this is important. Not for me, but I can imagine high-performance systems where this might be important.
I also think things like mmap(2) and even open(2) use the same functionality as hardlinks to keep a file's inode active so that even if the file gets unlink(2)ed, the inode remains to allow the process continued access, and only once the process closes it does the file really go away. This allows for much safer temporary files (if you can get the open and unlink to happen atomically, which there may be a POSIX API for that I'm not remembering, then you really have a safe temporary file) where you can read/write your data without anyone being able to access it. Well, that was true before /proc gave everyone the ability to look at your file descriptors, but that's another story.
说到这里,恢复一个在进程a中打开,但在文件系统中未链接的文件需要使用硬链接来重新创建inode链接,这样当打开该文件的进程关闭或离开时,该文件不会消失。
在进行增量备份时,硬链接非常有用。例如,请参阅rsnapshot。这个想法是使用硬链接进行复制:
拷贝备份号n到n + 1 拷贝备份n - 1到n ... 拷贝备份0到备份1 用任何更改过的文件更新备份0。
除了您所做的任何更改之外,新的备份不会占用任何额外的空间,因为所有增量备份都将指向未更改的文件的同一组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
这告诉我们
1st column: the file mode for the soft and hard links differ soft link: lrwxr-xr-x filetype: l = symbolic link owner permissions: rwx = readable, writable, executable group permissions: r-x = readable, not writable, executable other permissions: r-x = readable, not writable, executable hard link: -rw-r--r-- filetype: - = regular file owner permissions: rw- = readable, writable, not executable group permissions: r-- = readable, not writable, not executable other permissions: r-- = readable, not writable, not executable 2nd column: number of links is higher for the hard linked files 5th column: the size of the soft link is smaller, because it's a reference as opposed to a copy last column: the symbolic link shows the linked-to file via ->
更改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只是一个指向不存在文件的链接。
另外:
硬链接的读取性能优于符号链接(微性能) 符号链接可以被复制,版本控制,等等。换句话说,它们是一个实际的文件。另一方面,硬链接的级别略低,您会发现,与符号链接相比,提供将硬链接作为硬链接而不是普通文件处理的工具较少
加上以上所有答案,查找硬链接和软链接文件的差异可以理解为:
在当前目录中有一个文件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选项)。它节省了不必要的搜索到不同的挂载点。
所以搜索硬链接比搜索软链接快一些(如果我错了或不清楚,请纠正)。
简单地说,硬链接:就是给一个文件添加一个新的名字,也就是说,一个文件可以同时有很多名字,所有的名字都是相等的,没有一个是优先的,硬链接并不是指复制文件的所有内容,并不是说创建一个新的文件,它只是创建一个可供选择的名字。
符号链接(symlink):是指向另一个文件的文件指针,如果符号链接指向一个已存在的文件,但该文件稍后被删除,则符号链接将继续指向相同的文件名,即使该文件名不再命名任何文件。
软链接:
软的或象征性的更像是原始文件....的捷径如果您删除原始的快捷方式失败,如果您只删除快捷方式,原始的不会发生任何变化。
软链接语法:ln -s Pathof_Target_file链接
输出:link -> ./Target_file
证明:readlink链接 同样,在ls -l链接输出中,您将看到lrwxrwxrwx中的第一个字母为l,这表明该文件是一个软链接。
删除链路:unlink链路
注意:如果你愿意,你的软链接即使从当前目录移动到其他地方也可以工作。在创建软链接时,请确保您给出的是绝对路径而不是相对路径。即(从/root/user/Target_file开始,而不是。/Target_file)
硬链接:
硬链接更多的是镜像副本或同一文件的多条路径。对file1做一些操作,它就会出现在文件2中。 删除一个仍然可以保留另一个。
inode(或文件)只有在所有(硬)链接或(同一文件)inode的所有路径都已删除时才会被删除。
一旦创建了硬链接,该链接就具有原始文件的inode。删除重命名或移动原始文件不会影响硬链接,因为它链接到底层inode。对inode上数据的任何更改都反映在引用该inode的所有文件中。
硬链接语法:ln Target_file链接
输出:将创建一个名称为link的文件,其索引节点号与Targetfile相同。
证明:ls -i link Target_file(检查它们的索引节点)
删除链接:rm -f link(像删除普通文件一样删除链接)
注意:符号链接可以跨文件系统,因为它们只是另一个文件的名称。而硬链接只在同一个文件系统中有效。
符号链接有一些硬链接所没有的特性:
Hard link point to the file content. while Soft link points to the file name. while size of hard link is the size of the content while soft link is having the file name size. Hard links share the same inode. Soft links do not. Hard links can't cross file systems. Soft links do. you know immediately where a symbolic link points to while with hard links, you need to explore the whole file system to find files sharing the same inode. # find / -inum 517333 /home/bobbin/sync.sh /root/synchro hard-links cannot point to directories.
硬链接有两个限制:
目录不支持硬链接。Linux不允许这样维护目录的非循环树结构。 不能跨文件系统创建硬链接。这两个文件必须在相同的文件系统上,因为不同的文件系统有不同的独立的inode表(两个文件在不同的文件系统上,但是具有相同的inode号将是不同的)。
What you think of as an ordinary "file" is actually two separate things: The data of a file, and a directory entry. When you create a hard link for a file, you actually create a second directory entry which refers to the same data. Both directory entries have the exact same functionality; each one can be used to open the file to read it. So you don't really have "a file plus a hard link", you have "file data with two directory entries". What you think of as deleting a file actually deletes a directory entry, and when the last directory entry for the data is deleted, then the data itself is deleted as well. For ordinary files that have only one directory entry, deleting the directory entry will delete the data as always. (While a file is opened, the OS creates a temporary link to the file, so even when you delete all directory entries, the data stays but disappears as soon as you close the file).
例如,创建文件a .txt,硬链接B.txt,然后删除a .txt。当您创建a .txt时,会创建一些数据,并创建一个目录条目a .txt。在创建硬链接时,创建了另一个目录条目B.txt,指向完全相同的数据。当您删除a .txt时,您仍然拥有所有数据和一个目录条目B.txt,就像您首先创建了一个文件B.txt一样。
软链接只是一个(几乎)普通的文件,只是它不包含数据,而是另一个目录条目的路径。如果你删除了软链接所指向的文件,那么软链接将包含一个不再指向目录条目的路径;它坏了。如果你删除软链接,就像删除任何其他文件一样,它指向的文件不受影响。
通过一个简单的例子可以看出硬链接和符号链接之间的区别。指向文件的硬链接将指向存储文件的位置,或者指向该文件的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”的任何内容,直到不再有硬链接指向它。
俗话说,一幅画胜过千言万语。以下是我对它的想象:
下面是我们如何得到这张照片的:
Create a name myfile.txt in the file system that points to a new inode (which contains the metadata for the file and points to the blocks of data that contain its contents, i.e. the text "Hello, World!": $ echo 'Hello, World!' > myfile.txt Create a hard link my-hard-link to the file myfile.txt, which means "create a file that should point to the same inode that myfile.txt points to": $ ln myfile.txt my-hard-link Create a soft link my-soft-link to the file myfile.txt, which means "create a file that should point to the file myfile.txt": $ ln -s myfile.txt my-soft-link
看看如果myfile.txt被删除(或移动)会发生什么:my-hard-link仍然指向相同的内容,因此不受影响,而my-soft-link现在什么都不指向。其他答案讨论了每种方法的利与弊。
从MSDN,
符号链接
A symbolic link is a file-system object that points to another file system object. The object being pointed to is called the target. Symbolic links are transparent to users; the links appear as normal files or directories, and can be acted upon by the user or application in exactly the same manner. Symbolic links are designed to aid in migration and application compatibility with UNIX operating systems. Microsoft has implemented its symbolic links to function just like UNIX links. Symbolic links can either be absolute or relative links. Absolute links are links that specify each portion of the path name; relative links are determined relative to where relative–link specifiers are in a specified path
绝对符号链接的一个例子
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对它的定义如下:
连接(也称为软链接)与硬链接的不同之处在于,它引用的存储对象是单独的目录,并且连接可以链接位于同一计算机上不同本地卷上的目录。否则,连接与硬链接的操作相同。
硬链接部分和结节部分的粗体部分显示了两者的基本区别。
命令在窗口中创建一个连接,导航到要创建链接的位置,然后输入:
mklink /J link_name target_path
一个目录条目链接一个结构:
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 */
...
}
然后你创建一个符号链接(可能是/200)到文件1,目录条目可能是这样的:
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 */
我刚刚发现了一个简单的方法来理解硬链接在一个常见的场景,软件安装。
有一天,我下载了一个软件到下载文件夹进行安装。在我做sudo make install后,一些可执行文件被cped到本地bin文件夹。这里,cp创建硬链接。我对这个软件很满意,但很快就意识到,从长远来看,下载并不是一个好地方。所以我把软件文件夹移动到源目录。好吧,我仍然可以像以前一样运行软件而不用担心任何目标链接的事情,就像在Windows中一样。这意味着硬链接可以直接找到inode和其他文件。
在这个答案中,当我说文件时,我指的是内存中的位置
所有保存的数据都使用称为inode的数据结构存储在内存中,每个inode都有一个inodennumber。inode号用于访问inode。到文件的所有硬链接可能有不同的名称,但共享相同的inode号。因为所有的硬链接都有相同的inodennumber(访问相同的inode),所以它们都指向相同的物理内存。
符号链接是一种特殊的文件。因为它也是一个文件,它将有一个文件名和一个inode号。如上所述,inode号访问指向数据的inode。现在,符号链接的特殊之处在于,符号链接中的inodennumbers访问那些指向另一个文件的“路径”的inode。更具体地说,符号链接中的inode号访问指向另一个硬链接的inode。
当我们在GUI中移动、复制、删除文件时,我们使用的是文件的硬链接,而不是物理内存。当我们删除一个文件时,我们正在删除该文件的硬链接。我们并没有清除物理内存。如果文件的所有硬链接都被删除,那么将无法访问存储的数据,尽管它可能仍然存在于内存中
我对使用的两点看法:
软链接可以用来缩短长路径名,例如:
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上的文件
我刚刚发现了一个简单的方法来理解硬链接在一个常见的场景,软件安装。
有一天,我下载了一个软件到下载文件夹进行安装。在我做sudo make install后,一些可执行文件被cped到本地bin文件夹。这里,cp创建硬链接。我对这个软件很满意,但很快就意识到,从长远来看,下载并不是一个好地方。所以我把软件文件夹移动到源目录。好吧,我仍然可以像以前一样运行软件而不用担心任何目标链接的事情,就像在Windows中一样。这意味着硬链接可以直接找到inode和其他文件。
硬链接是Unix,它在Unix和Linux中都是旧的,但符号链接在Linux中是新的。
硬链接inode与原始文件inode相同。但是symbolik链接索引节点不同于原始文件索引节点。
硬链接文件的字节大小与原始文件的字节大小相同。但是符号链接文件的字节大小不像原始文件的字节大小。符号链接文件大小小于原始文件大小。
硬链接是原始文件的镜像副本。符号链接或软链接就像窗口中的快捷方式。
如果您删除原始文件,硬链接将保留其文件,您可以看到硬链接文件的内容。在符号链接中,如果删除原始文件,其符号链接将断开,符号链接仍然保留,但不能显示符号链接内容。
符号链接是新的,它有很多特点,但硬链接是旧的,这就是为什么它有较少的特点。
让我们用终端做一些硬的和象征性的链接: Echo“为什么这么严重”> file.txt
硬链接: Ln file.txt file_hard
symbolick链接: Ln -s file.txt file_sym
让我们看看inode的内容: ls李津
推荐文章
- 如何生成一个核心转储在Linux上的分段错误?
- 在Python中如何在Linux和Windows中使用“/”(目录分隔符)?
- 使用sh shell比较字符串
- 只列出UNIX中的目录
- 如何限制从grep返回的结果的数量?
- 如何管道列表的文件返回的找到命令到猫查看所有文件
- 以相对于当前目录的路径递归地在Linux CLI中列出文件
- 如何使用xargs复制名称中有空格和引号的文件?
- 在makefile中抑制命令调用的回声?
- Shell脚本for循环语法
- read()和recv(), send()和write()之间有什么区别?
- 如何将多行输出连接到一行?
- 在Ubuntu中创建一个目录的符号链接
- 在Unix中删除回车
- 如何在vi文本编辑器中获得文件的sudo访问权限?