硬链接算作普通文件吗?

硬链接算作普通文件吗?

我想知道是否有一种方法可以注册它,但由于大多数现代搜索引擎不能很好地处理长度超过 5 个单词的短语,因此我需要一些帮助。

我想知道这一点,因为我正在制作一个 bash 脚本,该脚本必须将文件注册为某些类型并相应地做出决定。从技术上讲,这对我的项目并不重要,但我很好奇。

另外,如果它们被认为是常规文件,那么有没有办法检查这些文件是否是硬链接而无需解析ls -i?有没有办法在不使用命令的情况下检查某个任意文件 X 是否硬链接到其他任意文件 Y find -i

答案1

在 Unix 风格的系统中,表示文件系统对象的数据结构(换句话说,数据关于文件)存储在所谓的“inode”中。

文件名只是到该 inode 的链接,称为“硬链接”。文件的第一个名称和任何后续链接之间没有区别。所以答案是“是”:硬链接是常规文件,事实上,常规文件是硬链接。

ls命令将显示该文件有多少个硬链接。

例如:

seumasmac@comp:~$ echo Hello > /tmp/hello.txt
seumasmac@comp:~$ ls -l /tmp/hello.txt 
-rw-rw-r-- 1 seumasmac seumasmac 6 Oct  4 13:05 /tmp/hello.txt

在这里我们创建了一个名为/tmp/hello.txt.1输出中的表示ls -l该文件有 1 个硬链接。这个硬链接就是文件名本身/tmp/hello.txt

如果我们现在创建另一个到该文件的硬链接:

seumasmac@comp:~$ ln /tmp/hello.txt /tmp/helloagain.txt
seumasmac@comp:~$ ls -l /tmp/hello*
-rw-rw-r-- 2 seumasmac seumasmac 6 Oct  4 13:05 /tmp/helloagain.txt
-rw-rw-r-- 2 seumasmac seumasmac 6 Oct  4 13:05 /tmp/hello.txt

您现在可以看到两个文件名都表明有 2 个指向该文件的硬链接。这两个都不是“正确的”文件名,它们都同样有效。我们可以看到它们都指向同一个 inode(在本例中为 5374043):

seumasmac@comp:~$ ls -i /tmp/hello*
5374043 /tmp/helloagain.txt  5374043 /tmp/hello.txt

有一个常见的误解,认为这对于目录来说是不同的。我听人们说ls目录返回的链接数是子目录的数量,.其中..包括不正确。或者,至少,虽然它会给你正确的数字,但它的正确原因却是错误的!

如果我们创建一个目录并执行 als -ld我们得到:

seumasmac@comp:~$ mkdir /tmp/testdir
seumasmac@comp:~$ ls -ld /tmp/testdir
drwxrwxr-x 2 seumasmac seumasmac 4096 Oct  4 13:20 /tmp/testdir

这表明该目录有 2 个硬链接。这些都是:

/tmp/testdir
/tmp/testdir/.

注意/tmp/testdir/..不是到此目录的链接,它是到/tmp.这告诉你为什么“子目录的数量”起作用。当我们创建一个新的子目录时:

seumasmac@comp:~$ mkdir /tmp/testdir/dir2
seumasmac@comp:~$ ls -ld /tmp/testdir
drwxrwxr-x 3 seumasmac seumasmac 4096 Oct  4 13:24 /tmp/testdir

您现在可以看到有 3 个指向/tmp/testdir目录的硬链接。这些都是:

/tmp/testdir
/tmp/testdir/.
/tmp/testdir/dir2/..

因此,由于它包含的条目,每个新子目录都会将链接计数增加一..

答案2

硬链接算作普通文件吗?

硬链接算作它们链接到的任何内容。您可以链接到同一文件系统上的任何内容。

mkdir test
cd !$

>file
ln -s file sym
mknod pipe p

ln file file2
ln -P sym sym2
ln pipe pipe2

ls -al

# sockets, too:
cat >tsock.c <<\EOD
#include <sys/socket.h>
#include <sys/un.h>
int main(int n, char **a)
{
        struct sockaddr_un test = { AF_UNIX, "socket" };
        int testfd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
        bind(testfd,(struct sockaddr *)&test,sizeof test);
}
EOD
make tsock
./tsock

ln socket socket2

ls -al

# even devices if you want:
sudo mknod mytty c 5 0
ln mytty mytty2
sudo chmod 666 mytty

ls -al
# notice permissions are on an object not on the links to it:
echo Hi, Kilroy! >mytty2  

每个到任何东西的硬链接都是等价的,只要有任何(编辑:非符号)链接到它(甚至是一个打开的文件描述符,对此我有令人尴尬的原因非常感激),底层对象就会一直存在。

系统将对目录链接强制执行规则,您将获得一个指向目录的命名链接,系统会自动添加其嵌入.链接和任何子目录的..链接(请注意,.上面的 ls 有两个链接),但这是对某些修改的显式检查承诺不循环的系统特权用户可以自己添加新链接。文件系统不在乎,它可以很好地表示任意目录图,但没有人愿意处理它们。

有(许多非 UNIX)文件系统不以这种方式工作,包括一些将其提供的替代品称为“硬链接”的文件系统。如果我没记错的话,OS X 已经在 HFS+ 上拼凑了一个等效的东西(它本身没有它们),我不知道它在这里如何忠实地保留语义。

相关内容