Linux硬链接,软链接
参考网上其他博客整理的内容
一. inode
1. 文件存储
文件是存储在硬盘上的,硬盘最小单位叫扇区(sector),每个扇区存储512字节。操作系统读取硬盘的时候,如果一个一个读取那效率很低,因此一次性读取多个扇区,即一次性读取一个块(block)。这种多个扇区组成的块,就是文件存取的最小单位。block
的大小最常见的是4KB,即连续8个sector
组成一个block
。
文件数据存储在块中,那么必须得有一个区域来存储文件的元信息,比如文件的创建者,修改日期,大小等等。这种存储文件元信息的区域就是inode,中文译“索引节点”
,也称i节点
。因为一次文件必须要占有一个inode,至少占用一个block。
2. inode的内容
inode包含了文件的元信息,其中有:
代码语言:javascript复制1.文件的字节数
2.文件的拥有者user ID
3.文件的组Group ID
4.文件的读,写,执行权限
5.文件的时间戳,共有三个:ctime指inode上一次改动的时间,mtime指文件内容上一次改动的时间,atime指文件上一次打开的时间
6.链接数,即有多少个文件名指向这个inode
7.文件数据block的位置
可以用stat命令,查看文件的inode信息
代码语言:javascript复制[root@localhost ~]# stat hello.txt
File: hello.txt
Size: 120 Blocks: 8 IO Block: 4096 regular file
Device: fd00h/64768d Inode: 36199745 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Context: unconfined_u:object_r:admin_home_t:s0
Access: 2021-04-29 16:19:11.408074363 0800
Modify: 2021-04-29 16:19:11.408074363 0800
Change: 2021-04-29 16:19:11.408074363 0800
Birth: -
inode编号
表面上我们是直接通过文件名打开文件,实际上,系统内部将这个过程分为三部:
- 系统通过文件名找到对应的inode号码
- 根据inode号码,获取inode里面的信息
- 根据inode的信息,找到文件所在的block,读出数据。
其实文件系统还要根据inode的信息,来判断用户是否有访问权限,有就指向对应数据的block,没有就返回权限拒绝。
代码语言:javascript复制[root@localhost ~]# ls -li hello.txt
36199745 -rw-r--r--. 1 root root 120 Apr 29 16:19 hello.txt
其中36199745就是inode号码
3. inode的大小
inode也会消耗硬盘空间的,所以格式化的时候,操作系统自动将硬盘分成两个区域。一个是数据区,存放文件数据。另一个是inode区,存放inode所包含的信息。每个inode的大小,一般是128字节或256字节。通常只需要关注inode总数而不需要关注单个单个inode的大小。
可以使用df -i查看硬盘分区inode总数和已使用情况
代码语言:javascript复制[root@localhost ~]# df -i
Filesystem Inodes IUsed IFree IUse% Mounted on
devtmpfs 223111 399 222712 1% /dev
tmpfs 230483 1 230482 1% /dev/shm
tmpfs 230483 773 229710 1% /run
tmpfs 230483 17 230466 1% /sys/fs/cgroup
/dev/mapper/cl-root 8910848 224485 8686363 3% /
/dev/sda1 65536 309 65227 1% /boot
tmpfs 230483 20 230463 1% /run/user/42
tmpfs 230483 11 230472 1% /run/user/0
4. inode的特性
由于inode和文件名分离,导致Unix/Linux系统具备以下几种特有的现像
1) 文件名包含特殊字符,无法删除。这时候可直接删除inode,就能够间接删除文件。
代码语言:javascript复制find ./* -inum 节点号 -delete
代码语言:javascript复制[root@localhost ~]# find ./* -inum 36199745 -delete
2) 移动文件或重命名文件,只是改动了文件名,并不影响到inode
3) 打开一个文件后,系统就用inode号码
来识别这个文件,不考虑文件名。
这种情况使得软件更新变得简单,可以在不关闭软件的情况下进行更新,不需要重启。因为系统通过inode
号码,识别运行中的文件,不通过文件名。更新的时候,新版文件以同样的文件名,生成一个新的inode
,不会影响到运行中的文件。等到下一次运行这个软件的时候,文件名就自动指向新版文件,旧版文件的inode
则被回收。
二. 硬链接
在Unix/Linux中是允许多个文件名与一个inode节点对应的,即多个文件名指向同一个inode。这就允许我们通过产生新的文件名来指向一个另外一个文件名所指向的inode,这就意味着我们可以通过不同的文件名(可能在同一路径也可能在不同路径)来访问同一个文件的数据内容,这种情况就可称为硬链接
可使用ln
命令来创建一个硬链接:
ln 源文件 新的目标文件
通过ln创建出来的新文件的inode号码将和原文件的inode号码一样,而在inode信息中的链接数将会加1
需要注意的是不能对目录做硬链接。
通过mkdir
命令创建一个新目录,其硬链接数应该有2
个,因为常见的目录本身为1
个硬链接,而目录下面的隐藏目录.(点号)
是该目录的又一个硬链接,也算是1
个连接数。
[root@localhost ~]# ls -li hello.txt
33796565 -rw-r--r--. 1 root root 120 Apr 29 16:48 hello.txt
[root@localhost ~]# ln hello.txt hello.hd1
[root@localhost ~]# ls -li hello.*
33796565 -rw-r--r--. 2 root root 120 Apr 29 16:48 hello.hd1
33796565 -rw-r--r--. 2 root root 120 Apr 29 16:48 hello.txt
这里可以看到hello.txt和hello.hd1的inode
号码,文件权限属性,文件大小都是一样的。然后inode的链接数由原来的1变为2.
所以硬链接本质就是一条文件名和inode的关联记录而已
三. 软链接(符号链接)
类似windows中的快捷方式,可以快速连接到目标文件和目录,称为软链接,或符号链接
首先看看怎么创建一个软链接,只需在ln命令后加一个s选项即可
代码语言:javascript复制ln -s 源文件 新的目标文件
那软链接和硬链接的区别有哪些?
软链接其实再创建一个独立的文件,但是文件会让数据的读取指向它链接的那个文件。即软链接会写上链接文件的文件名。
代码语言:javascript复制[root@localhost ~]# ln -s hello.txt hello.soft1
[root@localhost ~]# ls -li hello.*
33796565 -rw-r--r--. 2 root root 120 Apr 29 16:48 hello.hd1
33726887 lrwxrwxrwx. 1 root root 9 Apr 29 16:56 hello.soft1 -> hello.txt
33796565 -rw-r--r--. 2 root root 120 Apr 29 16:48 hello.txt
我们发现软链接文件的inode号确实和原文件不一样,并且它的大小只有9个字节(刚好的hello.txt
文件名的长度)。
这意味着软链接文件hello.soft1
会依赖于原文件hello.txt
而存在,如果hello.txt
被删除了,则hello.soft1
会找不到原文件,因为其指向的是原文件的文件名,而不是原文件的inode
号码
四. 测试区别
假设当前目录下有一个原文件hello.txt
,两个硬链接文件hello.hd1
,hello.hd2
和两个软链接文件hello.soft1
,hello.soft2
[root@localhost ~]# ls -li hello.*
33796565 -rw-r--r--. 3 root root 120 Apr 29 16:48 hello.hd1
33796565 -rw-r--r--. 3 root root 120 Apr 29 16:48 hello.hd2
33726887 lrwxrwxrwx. 1 root root 9 Apr 29 16:56 hello.soft1 -> hello.txt
36199747 lrwxrwxrwx. 1 root root 9 Apr 29 17:00 hello.soft2 -> hello.txt
33796565 -rw-r--r--. 3 root root 120 Apr 29 16:48 hello.txt
现在删除文件hello.txt
,然后在查看相关信息
[root@localhost ~]# rm -f hello.txt
[root@localhost ~]# ls -li hello.*
33796565 -rw-r--r--. 2 root root 120 Apr 29 16:48 hello.hd1
33796565 -rw-r--r--. 2 root root 120 Apr 29 16:48 hello.hd2
33726887 lrwxrwxrwx. 1 root root 9 Apr 29 16:56 hello.soft1 -> hello.txt
36199747 lrwxrwxrwx. 1 root root 9 Apr 29 17:00 hello.soft2 -> hello.txt
可以发现硬链接inode信息中链接数从3变成2
这时候查看文件内容
代码语言:javascript复制[root@localhost ~]# cat hello.hd1
hello
hello
hello
hello
... #省略后续输出
代码语言:javascript复制[root@localhost ~]# cat hello.soft1
cat: hello.soft1: No such file or directory
上面说过软链接得依赖于原文件,所以这里当原文件被删除后,软链接文件就不能正常指向了。但硬链接文件还能输出的原因是inode
还存在,删除了原文件只是让inode
的链接数减少1。所以要当inode的链接数变为0时,inode才会被系统回首,文件的内容才会被删除。
[root@localhost ~]# rm -f hello.hd1
[root@localhost ~]# ls -li hello.*
33726887 lrwxrwxrwx. 1 root root 9 Apr 29 16:56 hello.soft1 -> hello.txt
36199747 lrwxrwxrwx. 1 root root 9 Apr 29 17:00 hello.soft2 -> hello.txt
[root@localhost ~]# find ./* -inum 33796565 #没有输出
[root@localhost ~]#
五. 文件特殊权限设置位S和沾附位T
(这部分内容只是补充记录)
1) 设置位S
为了让一般使用者临时具有该文件所属主/组的执行权限。比如/usr/bin/passwd在执行它的时候需要去修改/etc/passwd和/etc/shadow等文件,这些文件除了root外,其他用户都没有写权限,但是又为了能让普通用户修改自己的密码,只能时临时让他们具有root的权限。所以这个s权限就是用来完成这个特殊任务的。s权限只能应用在二进制的可执行文件上。
2) 沾附位
只针对目录生效,它表示只能让所属主以及root可以删除(重命名/移动)该目录下的文件。比如/tmp目录本来就是任何用户都可以读写,如果别人可以任意删除(重命名/移动)自己的文件,那岂不是很危险,所以这个t权限就是为了解决这个问题。
六. 参考网站
1) 硬链接和软链接
https://www.cnblogs.com/llife/p/11470668.html
https://www.cnblogs.com/zsh-blogs/p/10570277.html
2) inode
https://www.cnblogs.com/zsh-blogs/p/10570277.html
3) 设置位S和沾附位T
https://www.cnblogs.com/zhangming-blog/articles/5956280.html