最近我在一次工作面试中被问到这个问题。我诚实地说,我知道符号链接的行为和如何创建一个,但不了解硬链接的使用,以及它与符号链接的区别。
当前回答
通过一个简单的例子可以看出硬链接和符号链接之间的区别。指向文件的硬链接将指向存储文件的位置,或者指向该文件的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”的任何内容,直到不再有硬链接指向它。
其他回答
在进行增量备份时,硬链接非常有用。例如,请参阅rsnapshot。这个想法是使用硬链接进行复制:
拷贝备份号n到n + 1 拷贝备份n - 1到n ... 拷贝备份0到备份1 用任何更改过的文件更新备份0。
除了您所做的任何更改之外,新的备份不会占用任何额外的空间,因为所有增量备份都将指向未更改的文件的同一组inode。
我刚刚发现了一个简单的方法来理解硬链接在一个常见的场景,软件安装。
有一天,我下载了一个软件到下载文件夹进行安装。在我做sudo make install后,一些可执行文件被cped到本地bin文件夹。这里,cp创建硬链接。我对这个软件很满意,但很快就意识到,从长远来看,下载并不是一个好地方。所以我把软件文件夹移动到源目录。好吧,我仍然可以像以前一样运行软件而不用担心任何目标链接的事情,就像在Windows中一样。这意味着硬链接可以直接找到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链接,这样当打开该文件的进程关闭或离开时,该文件不会消失。
另外:
硬链接的读取性能优于符号链接(微性能) 符号链接可以被复制,版本控制,等等。换句话说,它们是一个实际的文件。另一方面,硬链接的级别略低,您会发现,与符号链接相比,提供将硬链接作为硬链接而不是普通文件处理的工具较少
一个目录条目链接一个结构:
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 */
推荐文章
- 如何从命令行通过mysql运行一个查询?
- 在创建守护进程时执行双fork的原因是什么?
- 对以制表符分隔的文件进行排序
- 如何使用查找命令从列表中查找所有具有扩展名的文件?
- 如何将文件指针(file * fp)转换为文件描述符(int fd)?
- 在Bash中获取日期(比当前时间早一天)
- Linux: kill后台任务
- 在OSX中永久设置PATH环境变量
- 如何在C程序中获取当前目录?
- 如何在Bash中逐行合并两个文件
- 如何从远程SSH会话发送数据到本地剪贴板
- 我如何得到bash完成工作与别名?
- SSH端口转发~/。ssh /配置文件?
- 如何将多个文件的内容追加到一个文件
- 如何进入每个目录并执行命令?