link 计数和 ls 命令

link count and ls command

我正在学习文件 link 计数。只有当 link 计数为 0 时,文件内容才会被删除。在我的测试中,该进程在目录“/home/hel/myfile”中打开一个文件并休眠 10(s)。同时我使用 "rm /home/hel/myfile" 删除它。然后我使用命令 "ls" 并显示没有这样的文件。但实际上文件还存在,因为fd还没有关闭。如果是这样,"ls" 无法显示文件是否真的存在。我对 "ls" 感到困惑。或者如何判断一个文件是否真的存在?

#include <fcntl.h>
#include <stdlib.h>

int main(void)
{
    int fd;

    fd = open("/home/hel/myfile", O_RDWR);
    if (fd < 0) {
        exit(-1);
    }
    sleep(10); // sleep 10(s) 
    close(fd);
    return 0;
}

文件名就像一个指向真实数据的标签。真实数据存储在an inode中。一个索引节点通常只有一个指向它的文件名,link 计数为一。但它可以有多个。

这是一个直观的例子。当你创建一个普通文件时,它会将你的数据放在一个新的索引节点中,并将文件名指向它。

$ echo "foo" > some/file

  "some/file" -> [data: "foo", links: 1]

当你制作另一个文件时,同样的事情会发生。

$ echo "bar" > another/file

  "some/file"     -> [data: "foo", links: 1]
  "another/file"  -> [data: "bar", links: 1]

但是如果你做一个hard link,现在inode有两个link。

$ ln some/file some/link

  "some/file"     -> [data: "foo", links: 2]
                      ^
  "some/link"    -----/     

  "another/file"  -> [data: "bar", links: 1]

事实上,普通文件很难link。除了文件名,没有什么可以区分 some/filesome/link。两者都不是 "real" 文件,它们都是 links.

如果 link 被删除,link 计数会减少。这就是为什么在某些语言中您调用 unlink 来删除文件的原因。

$ rm some/file

  "some/link"     -> [data: "foo", links: 1]  

  "another/file"  -> [data: "bar", links: 1]

当它到达0时,inode可以被覆盖。数据仍然存在,但没有任何指向它的东西。这就是您有时可以恢复已删除文件的原因。

$ rm some/link

                     [data: "foo", links: 0]

  "another/file"  -> [data: "bar", links: 1]

文件句柄呢?他们不会更改 link 计数。相反,在 Unix(不是 Windows)上,操作系统会跟踪给定 inode 有多少个打开的句柄。只要有一个打开的句柄,它就不会允许 inode 被覆盖。

fd = open("another/file", O_RDWR);

                         [data: "foo", links: 0]

                  fd  ---\
                         \/
      "another/file"  -> [data: "bar", links: 1]

$ rm another/file

                         [data: "foo", links: 0]

                   fd -> [data: "bar", links: 0]

close(fd);

                         [data: "foo", links: 0]

                         [data: "bar", links: 0]

这使您可以执行诸如创建临时文件、打开句柄以对其进行读取和写入以及立即将其删除等操作。然后程序可以继续读写临时磁盘存储,但没有人可以看到该文件。