AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 748182
Accepted
dr_
dr_
Asked: 2023-06-07 16:13:27 +0800 CST2023-06-07 16:13:27 +0800 CST 2023-06-07 16:13:27 +0800 CST

'..'真的是一个硬链接吗?

  • 772

这是一个有点理论性的问题,但为事物使用专有名称很重要。

在 UNIX/Linux 文件系统中,..指向父目录。

但是,我们知道硬链接不能指向目录,因为这有可能破坏文件系统的无环图结构并导致命令在无限循环中运行。

那么,..真的是硬链接(如.)吗?这将使它成为一种特殊类型的硬链接,不受目录限制,但对于所有目的来说都像一个硬链接。

或者是一个特殊的 inode 映射,硬编码到文件系统中,不应该称为硬链接?

filesystems
  • 4 4 个回答
  • 1083 Views

4 个回答

  • Voted
  1. Best Answer
    Gilles 'SO- stop being evil'
    2023-06-07T16:51:19+08:002023-06-07T16:51:19+08:00

    这取决于文件系统。大多数文件系统遵循传统的 Unix 设计,其中.和..是硬链接。目录的硬链接数是 2 + n,其中 n 是子目录的数量:即目录父目录中的条目、目录自己的条目.以及每个子目录的..条目。每次创建、删除或移入或移出目录时,都会更新硬链接计数。请参阅为什么新目录在添加任何内容之前的硬链接数为 2?以获得更详细的解释。

    一些文件系统偏离了这一传统,特别是btrfs。

    我们知道硬链接不能指向目录

    这是不准确的措辞。更准确地说,您不能使用ln实用程序或link系统调用或类似方法创建到目录的硬链接,因为内核会阻止您。调用mkdir确实会创建到新目录父目录的硬链接。这是在文件系统上创建到目录的新硬链接的唯一方法(相反,删除目录是删除到目录的硬链接的唯一方法)。

    另外,请注意,将硬链接视为“指向”主文件是一种误导。与符号链接不同,硬链接不是定向的。当一个文件有多个硬链接时,它们是等价的。在以下顺序之后:

    mkdir a b
    touch a/file
    ln a/file b/file
    

    文件系统中没有任何东西b/file次于a/file. 这两个目录条目都引用同一个文件。它们都是文件的硬链接。

    • 14
  2. user10489
    2023-06-07T19:32:24+08:002023-06-07T19:32:24+08:00

    这是一个实现细节。

    在符合 POSIX 的文件系统中,..充当硬链接。

    然而,一些文件系统只是模拟它,并不实际将它存储在磁盘上。

    出于功能目的,假设您没有文件系统损坏,区别是没有意义的。(如果这样做,fsck 旨在解决此问题。)

    非 posix 完全模拟硬链接的失败之一是硬链接计数未指示目录内子目录的正确数量。findoption选项-noleaf禁用使用此链接计数的优化。

    • 4
  3. Philip Couling
    2023-06-07T20:07:59+08:002023-06-07T20:07:59+08:00

    作为吉尔斯回答的补充,我认为值得关注这些词并对其进行扩展:

    另外,请注意,将硬链接视为“指向”主文件是一种误导。

    理解 linux 中文件的概念模型非常重要,其中目录中的每个名称都是指向可能指向数据的“inode”的“链接”。

    这里令人困惑的是“硬链接”和“符号链接”的命名约定听起来像是同一事物的两种风格。他们不是!

    一个常规文件是:

    link -> x 
            | Inode -> Data
    

    “硬链接文件”也不例外:

    link_a -> x
              | Inode -> Data
    link_b -> x
    

    但是符号链接是:

    original_file_name -> x
                          | Inode -> Data
    
    sym_link_name      -> x
                          | Inode -> File name "original_file_name"
    

    那么为什么不能硬链接目录呢?

    我得到的最好的解释来自于这个。该..条目必须在目录中维护。如果您有多个指向目录本身的名称,那么您可能有多个父级,这是不可能的,因为..只能存在一次,就像每个其他可能的名称在目录中只能存在一次一样。

    • 4
  4. CodeGnome
    2023-06-08T06:34:56+08:002023-06-08T06:34:56+08:00

    .并且..是指向 inode 的特殊硬链接

    从纯粹实用主义的角度来看,.. 是一个硬链接。在 Linux 上,当从挂载卷的顶层调用时,它被视为挂载点的硬链接,在 Linux 和 macOS 上,/硬链接.和..inode 2 作为一种特殊情况。

    更多详情

    正如其他人指出的那样,.和..都是支持 inode 的文件系统上 inode 的硬链接。有一些文件系统没有索引节点,但这是一个附带问题。出于实际目的,无论系统是否直接支持索引节点,硬链接都只是指向给定文件系统上的相同元数据块。有时硬链接是文件系统上的真实链接,有时它是合成的,因为 POSIX 系统期望.并且..由于历史原因而存在。无论哪种方式,它都被视为到目录的硬链接,并且某些文件系统(例如 HFS+)确实允许您硬链接不跨越文件系统边界的目录。

    目录的硬链接

    MacOS确实允许 HFS+ 文件系统上的硬链接指向目录,因为这在历史上是 Time Machine 优化磁盘使用的方式。但是,较新版本的 Time Machine 使用 APFS 文件系统和文件系统快照,因此除了向后兼容性外,实际上不需要此例外,并且它不适用于 APFS。不要依赖它。

    因此,通常是文件系统本身决定目录是否可以硬链接。在 Ubuntu 22.04 上,如果系统允许,lnman 1 ln实用程序支持目录链接:

           -d, -F, --directory
                  allow  the  superuser to attempt to hard link directories (note:
                  will probably fail due to system restrictions, even for the  su‐
                  peruser)
    
    

    可能让大多数人感到困惑的部分是挂载点。如果您将磁盘安装为/mnt/foo,则cd /mnt/foo; ls -ld ..指向安装点的索引节点,在本例中为 的索引节点/mnt。挂载目录的硬链接并..没有真正跨越文件系统边界,因为它只是查看 /mnt/foo 的硬链接(无论当前是否安装了一个卷,它都存在)或者它被特殊处理内核支持挂载的卷。这很可能是一个实现细节,我无法指出任何与之相关的内核源代码,但从功能上讲,它在技术上仍然是一个硬链接,因为它..指向一个索引节点,而不是一个指向文件名的软链接。

    您可以使用以下方法自行测试:

    cd /
    stat .
    stat ..
    

    在 Linux 和 macOS 上,当使用-x标志调用时,您会看到两者.都..指向 inode 2。许多文件系统为坏块保留 inode 1。

    由于您可以在某些文件系统上创建指向目录的硬链接,包括带有debugfs的 EXT3/4 ,因此您不能硬链接目录并不是真的。通常不支持它以确保目录图是非循环的,并且像fsck这样的工具会抱怨除当前工作目录 ( ) 和父目录之外的.任何..文件系统不支持目录硬链接的文件系统之外的硬链接目录.目录 ( ..) 作为一个特殊的遗留案例。

    • 1

相关问题

  • 我应该在 NAS 的 SD 卡中使用哪个文件系统?

  • 如何提前知道 .zip 内部是否有父目录

  • Virtualbox 动态分配磁盘 *.vdi 不断增长

  • du/df 和 ls 报告不同的磁盘使用情况

  • Linux 内核开发人员如何处理数百万行代码的工作?他们是一种方法吗?[关闭]

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    模块 i915 可能缺少固件 /lib/firmware/i915/*

    • 3 个回答
  • Marko Smith

    无法获取 jessie backports 存储库

    • 4 个回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    user12345 无法获取 jessie backports 存储库 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl 为什么大多数 systemd 示例都包含 WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve