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
    • 最新
    • 标签
主页 / ubuntu / 问题 / 1073802
Accepted
Sergiy Kolodyazhnyy
Sergiy Kolodyazhnyy
Asked: 2018-09-10 18:29:08 +0800 CST2018-09-10 18:29:08 +0800 CST 2018-09-10 18:29:08 +0800 CST

如果 Linux 上的一切都是文件,那么什么是目录?

  • 772

初学者经常听到一句话“Linux/Unix 上的一切都是文件”。但是,目录是什么?它们与文件有何不同?

directory files
  • 1 1 个回答
  • 10155 Views

1 个回答

  • Voted
  1. Best Answer
    Sergiy Kolodyazhnyy
    2018-09-10T18:29:08+08:002018-09-10T18:29:08+08:00

    注意:最初这是为了支持我对为什么命令中的当前目录被ls标识为链接到自身的答案而编写的?但我觉得这是一个值得独立存在的话题,因此有这个问答。

    了解 Unix/Linux 文件系统和文件:一切都是 inode

    本质上,目录只是一个特殊文件,其中包含条目列表及其 ID。

    在我们开始讨论之前,重要的是要区分几个术语并了解目录和文件的真正含义。您可能听说过 Unix/Linux 的“一切都是文件”的说法。嗯,用户通常理解为文件是这样的:/etc/passwd- 具有路径和名称的对象。实际上,名称(无论是目录、文件还是其他)只是一串文本 - 实际对象的属性。该对象称为inode或 I-number,并存储在磁盘上的 inode 表中。开放程序也有 inode 表,但这不是我们现在关心的问题。

    Unix 的目录概念就像 Ken Thompson 在1989 年的一次采访中所说的那样:

    ...然后其中一些文件是仅包含名称和 I 号的目录。

    从丹尼斯·里奇 1972 年的演讲中可以得出一个有趣的观察结果:

    “……目录其实只是一个文件,但它的内容是由系统控制的,内容是其他文件的名称。(目录在其他系统中有时也称为目录。)”

    ...但是谈话中没有提到 inode 的任何地方。然而,1971 年的手册指出format of directories:

    文件是目录这一事实由其 i 节点条目的标志字中的位指示。

    目录条目长 10 个字节。第一个词是该条目表示的文件的 i 节点,如果非零;如果为零,则该条目为空。

    所以它从一开始就在那里。

    目录和 inode 配对也在UNIX 文件系统中的目录结构如何存储?. 目录本身是一种数据结构,更具体地说:对象列表(文件和 inode 编号)指向有关这些对象的列表(权限、类型、所有者、大小等)。所以每个目录都包含自己的 inode 编号,然后是文件名及其 inode 编号。最著名的是inode #2,它是/directory。(注意,虽然/dev和/run是虚拟文件系统,所以由于它们是文件系统的根文件夹,它们也有 inode 2; 即一个inode 在它自己的文件系统上是唯一的,但是附加了多个文件系统,你有非唯一的inode)。从链接问题借来的图表可能更简洁地解释了它:

    目录 iNode 块

    stat()根据 Linux,存储在 inode 中的所有信息都可以通过系统调用访问man 7 inode:

    每个文件都有一个包含有关该文件的元数据的 inode。应用程序可以使用返回 stat 结构的 stat(2)(或相关调用)或返回 statx 结构的 statx(2) 检索此元数据。

    是否可以仅知道其 inode 编号( ref1,ref2 )来访问文件?在某些 Unix 实现上是可能的,但它绕过了权限和访问检查,所以在 Linux 上它没有实现,你必须遍历文件系统树(find <DIR> -inum 1234例如通过)来获取文件名及其对应的 inode。

    在源代码级别,它在Linux 内核源代码中定义,也被许多在 Unix/Linux 操作系统上运行的文件系统采用,包括 ext3 和 ext4 文件系统(Ubuntu 默认)。有趣的是:由于数据只是信息块,Linux 实际上有inode_init_always 函数可以确定一个 inode 是否是管道 ( inode->i_pipe)。是的,套接字和管道在技术上也是文件——匿名文件,在磁盘上可能没有文件名。FIFO和Unix-Domain 套接字在文件系统上确实有文件名。

    数据本身可能是唯一的,但 inode 编号不是唯一的。如果我们有一个名为 foobar 的指向 foo 的硬链接,那么它也将指向 inode 123。该 inode 本身包含有关该 inode 占用了哪些实际磁盘空间块的信息。从技术上讲,这就是您可以.链接到目录文件名的方式。好吧,几乎:您不能自己在 Linux 上创建指向目录的硬链接,但是文件系统可以以非常规范的方式允许指向目录的硬链接,这限制了只有硬链接.和..硬链接。

    目录树

    文件系统将目录树实现为树数据结构之一。尤其是,

    • ext3 和 ext4 使用 HTree
    • xfs 使用 B+ 树
    • zfs 使用哈希树

    这里的关键点是目录本身是树中的节点,子目录是子节点,每个子节点都有一个返回父节点的链接。因此,对于目录链接,裸目录(指向目录名称的/home/example/链接和指向 self的链接/home/example/.)的 inode 计数最少为 2,并且每个额外的子目录都是一个额外的链接/节点:

    # new directory has link count of 2
    $ stat --format=%h .
    2
    # Adding subdirectories increases link count
    $ mkdir subdir1
    $ stat --format=%h .
    3
    $ mkdir subdir2
    $ stat --format=%h .
    4
    # Count of links for root
    $ stat --format=%h /
    25
    # Count of subdirectories, minus .
    $ find / -maxdepth 1 -type d | wc -l
    24
    

    Ian D. Allen 的课程页面上的图表显示了一个简化的非常清晰的图表:

    WRONG - names on things      RIGHT - names above things
    =======================      ==========================
    
        R O O T            --->         [etc,bin,home]   <-- ROOT directory
       /   |   \                         /    |      \
    etc   bin   home       --->  [passwd]  [ls,rm]  [abcd0001]
     |   /   \    \                 |      /    \       |
     |  ls   rm  abcd0001  --->     |  <data>  <data>  [.bashrc]
     |               |              |                   |
    passwd       .bashrc   --->  <data>                <data>
    

    右图中唯一不正确的是文件在技术上不被认为位于目录树本身:添加文件对链接计数没有影响:

    $ mkdir subdir2
    $ stat --format=%h .
    4
    # Adding files doesn't make difference
    $ cp /etc/passwd passwd.copy
    $ stat --format=%h .
    4
    

    像访问文件一样访问目录

    引用Linus Torvalds 的话:

    “一切都是文件”的重点不是你有一些随机的文件名(实际上,套接字和管道表明“文件”和“文件名”彼此无关),而是你可以使用 common操作不同事物的工具。

    考虑到目录只是文件的一种特殊情况,自然必须有 API 允许我们以与常规文件类似的方式打开/读取/写入/关闭它们。

    这就是dirent.hC 库出现的地方,它定义了dirent结构,您可以在man 3 readdir中找到它:

       struct dirent {
           ino_t          d_ino;       /* Inode number */
           off_t          d_off;       /* Not an offset; see below */
           unsigned short d_reclen;    /* Length of this record */
           unsigned char  d_type;      /* Type of file; not supported
                                          by all filesystem types */
           char           d_name[256]; /* Null-terminated filename */
       };
    

    因此,在您的 C 代码中,您必须定义struct dirent *entry_p,并且当我们打开目录opendir()并使用 开始读取它时readdir(),我们会将每个项目存储到该entry_p结构中。当然,每个项目都将包含dirent上面显示的模板中定义的字段。

    可以在我关于如何在当前工作目录中列出文件及其 inode 编号的回答中找到有关其工作原理的实际示例。

    请注意,关于 fdopen 的 POSIX 手册指出“点和点点的目录条目是可选的”,而readdir 手动状态 struct dirent只需要具有d_name和d_ino字段。

    关于“写入”目录的注意事项:写入目录正在修改其条目“列表”。因此,创建或删除文件与目录写入权限直接相关,添加/删除文件是对该目录的写入操作。

    • 27

相关问题

  • 如何为我的罗技网络摄像头创建 udev 规则 [关闭]

  • 如何从命令行获取文件的 mime 类型?

  • examples.desktop 是做什么的?

  • 查看或转换 MDI 文件 [关闭]

  • 如何在不更改名称的情况下隐藏目录或文件?

Sidebar

Stats

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

    如何运行 .sh 脚本?

    • 16 个回答
  • Marko Smith

    如何安装 .tar.gz(或 .tar.bz2)文件?

    • 14 个回答
  • Marko Smith

    如何列出所有已安装的软件包

    • 24 个回答
  • Marko Smith

    无法锁定管理目录 (/var/lib/dpkg/) 是另一个进程在使用它吗?

    • 25 个回答
  • Martin Hope
    Flimm 如何在没有 sudo 的情况下使用 docker? 2014-06-07 00:17:43 +0800 CST
  • Martin Hope
    Ivan 如何列出所有已安装的软件包 2010-12-17 18:08:49 +0800 CST
  • Martin Hope
    La Ode Adam Saputra 无法锁定管理目录 (/var/lib/dpkg/) 是另一个进程在使用它吗? 2010-11-30 18:12:48 +0800 CST
  • Martin Hope
    David Barry 如何从命令行确定目录(文件夹)的总大小? 2010-08-06 10:20:23 +0800 CST
  • Martin Hope
    jfoucher “以下软件包已被保留:”为什么以及如何解决? 2010-08-01 13:59:22 +0800 CST
  • Martin Hope
    David Ashford 如何删除 PPA? 2010-07-30 01:09:42 +0800 CST

热门标签

10.10 10.04 gnome networking server command-line package-management software-recommendation sound xorg

Explore

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

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve