前言
类似Windows系统,Linux系统在进行文件管理时,也会引入链接概念。而链接又分为软链接和硬链接,两种链接适用于不同场合、不同用途,各有优缺点。在介绍软硬两种链接之前,需要先引入inode的概念。
Inode:
系统在管理文件时,为了有序寻址,会将元数据(metadata)和用户数据(userdata)分开存放。元数据是指文件各类附加属性,如ls –l命令中显示的文件类型、权限、属主属组、文件大小、修改时间以及文件名等信息;而用户数据是指真实的对用户有用的数据。Linux不同路径下可以创建相同文件名称的文件,对于计算机系统来说,识别二进制数字比直接的文件名更为快捷。所以Linux系统用不同的数字来标识不同的文件,而此数字就是inode号,即索引节点号(index node)。元数据中的inode才是系统识别文件的唯一标识符。
查看inode相关的命令:ls –i 、 stat 、 df –i
[root@Hisen /]# ls -i 393219 bin 524290 home 917506 media 1048581 opt 131074 selinux 393217 tmp 2 boot 786434 lib 12503 misc 1 proc 393220 srv 2 usr 4 dev 262146 lib64 917507 mnt 1048578 root 1 sys 2 var 1179649 etc 11 lost+found 2507 net 131075 sbin 131099 testdir
[root@Hisen /]# stat bin/ File: `bin/' Size: 4096 Blocks: 8 IO Block: 4096 directory Device: fd00h/64768d Inode: 393219 Links: 2 Access: (0555/dr-xr-xr-x) Uid: (0/root) Gid: (0/root) Access: 2016-10-19 11:58:26.863958830 +0800 Modify: 2016-10-18 09:07:21.360998536 +0800 Change: 2016-10-18 09:07:21.360998536 +0800
[root@Hisen /]# df -i Filesystem Inodes IUsed IFree IUse% Mounted on /dev/mapper/vg0-root 1310720 7105 1303615 1% / tmpfs 125596 1 125595 1% /dev/shm /dev/sda1 51200 38 51162 1% /boot /dev/mapper/vg0-usr 655360 100297 555063 16% /usr /dev/mapper/vg0-var 1310720 3150 1307570 1% /var /dev/sdb 1310720 12 1310708 1% /mnt/cdrom
一个节点是一个表项,其中包含有关文件信息的元数据,包括:
文件类型
权限
UID
GID
硬链接数
文件大小
时间戳
指针
其他数据
简而言之,对于Linux系统来说,所有的目录映射都是文件之间的inode号映射。
由于每个分区都有着自身的一套inode号,在执行类似于cp和mv的命令,会对目标文件的inode号有何影响?
cp和inode:
[root@Hisen ~]# cp /Hisen/testfile1 /tmp/ [root@Hisen ~]# ll -i /Hisen/testfile1 /tmp/testfile1 917512 -rw-r--r-- 1 root root 0 Oct 19 12:51 /Hisen/testfile1 393361 -rw-r--r-- 1 root root 0 Oct 19 13:19 /tmp/testfile1
cp命令复制文件的原理:分配一个空闲的inode号,在inode表中生成新条目在目录中创建一个目录项,将名称与inode编号关联拷贝数据生成新的文件。
mv和inode:
①如果mv命令的目标和源在相同的文件系统
[root@Hisen ~]# rm -rf /tmp/testfile1 [root@Hisen ~]# ll -i /Hisen/testfile1 917512 -rw-r--r-- 1 root root 0 Oct 19 12:51 /Hisen/testfile1 [root@Hisen ~]# mv /Hisen/testfile1 /tmp/ [root@Hisen ~]# ll -i /tmp/testfile1 917512 -rw-r--r-- 1 root root 0 Oct 19 12:51 /tmp/testfile1
用新的文件名创建对应新的目录项,删除旧目录条目对应的旧的文件名,不影响inode表(除时间戳)或磁盘上的数据位置:没有数据被移动!
②如果目标和源在一个不同的文件系统
将sdb硬盘挂载至/mnt/cdrom下:
[root@Hisen ~]# mount /dev/sdb on /mnt/cdrom type ext4 (rw)
/Hisen/testfile1的原始inode:
[root@Hisen ~]# ll -i /Hisen/testfile1 917512 -rw-r--r-- 1 root root 0 Oct 19 12:51 /Hisen/testfile1
将/Hisen/testfile1移动至不同分区的/mnt/cdrom下:
[root@Hisen ~]# mv /Hisen/testfile1 /mnt/cdrom/ [root@Hisen ~]# ll -i /mnt/cdrom/testfile1 12 -rw-r--r-- 1 root root 0 Oct 19 12:51 /mnt/cdrom/testfile1
rm和inode:
删除文件其实就是释放inode号,而之前的用户数据则依然保存在硬盘内部,只不过系统会将没有inode号的数据标记为空闲状态。
硬链接
如果用人来形容的话,inode号就相当于身份证号码,在同分区内唯一标识。而硬链接就相当于将我们重新取个名字,但在本质上,都是我们自己本身。
命令:ln filename [linkname ]
用ls –l命令可以查看当前文件的硬链接数:
[root@Hisen Hisen]# ll -di /Hisen/ 917509 drwxr-xr-x 3 root root 4096 Oct 19 13:35 /Hisen/
其中数字3就代表当前目录的硬链接数。那么这3次硬链接又是从何而来?
/Hisen/目录本身inode号:
[root@Hisen ~]# ll -id /Hisen/ 917509 drwxr-xr-x 3 root root 4096 Oct 19 13:35 /Hisen/
/Hisen/目录下所有子文件inode信息:
[root@Hisen ~]# ll -ai /Hisen/ 917509 drwxr-xr-x 3 root root 4096 Oct 19 13:35 . 2 dr-xr-xr-x. 26 root root 524288 Oct 19 12:50 .. 917511 drwxr-xr-x 2 root root 4096 Oct 19 12:52 testdir1
子目录/Hisen/testdir1/目录下子文件inode信息:
[root@Hisen ~]# ll -ai /Hisen/testdir1/ 917511 drwxr-xr-x 2 root root 4096 Oct 19 12:52 . 917509 drwxr-xr-x 3 root root 4096 Oct 19 13:35 .. 917513 -rw-r--r-- 1 root root 0 Oct 19 12:52 testfile2
可以看出:/Hisen/自身目录下有·和··的隐藏目录,而·目录的inode号跟自身相同,··目录的inode号跟父目录相同,而/Hisen/testdir1/目录下··的inode号又跟/Hisen/目录相同。
因此默认的目录下都会出现·和··两个隐藏目录项,其中·代表当前目录的硬链接,··代表父目录对当前目录的硬链接,所以每个目录文件都至少有2次硬链接。由于当前目录的子目录也会对父目录进行硬链接,所以每个目录的硬链接数等于2加上子目录数。而在/Hisen/目录下,有一个testdir1的目录文件,所以硬链接数为3。
既然我们知道目录的硬链接数从何而来,那么接下来再看看文件的硬链接数吧。
将/Hisen/testdir1/下的testfile2硬链接至/tmp/下,链接名为link01:
[root@Hisen ~]# ln /Hisen/testdir1/testfile2 /tmp/link01 [root@Hisen ~]# ll -i /Hisen/testdir1/testfile2 /tmp/link01 917513 -rw-r--r-- 2 root root 6 Oct 19 14:30 /Hisen/testdir1/testfile2 917513 -rw-r--r-- 2 root root 6 Oct 19 14:30 /tmp/link01
上例可知硬链接一次文件,该文件的硬链接次数增加1。
/Hisen/testdir1/testfile2文件中只保存‘Hisen’五个英文字符,接下来我们删除/Hisen/testdir1/testfile2,看看link01文件是否能正常访问。
[root@Hisen ~]# rm -rf /Hisen/testdir1/testfile2 [root@Hisen ~]# cat /tmp/link01 Hisen
由上可知,硬链接映射同一个inode号,删除其中一个文件名,并不影响其他文件名的使用。多个硬链接名之间并无任何依赖关系存在。
如果将文件跨分区进行硬链接,会出现设备结果?
[root@Hisen ~]# ln /Hisen/testdir1/testfile2 /mnt/cdrom/ ln:creating hard link `/mnt/cdrom/testfile2' => `/Hisen/testdir1/testfile2': Invalid cross-device link
上面例子提示,无法跨设备进行硬链接。是因为,每个分区都会有自己的inode号,不同的分区下相同的inode号很可能有不同的用途。
关于路径,硬链接既可以使用当前绝对路径(见上例),也可以使用相对路径。其中相对路径又分为:相对于当前目录和相对于链接目标文件的路径。
相对于当前路径的硬链接:
[root@Hisen testdir1]# ln testfile2 /tmp/link02 [root@Hisen testdir1]# ll -i testfile2 /tmp/link02 917513 -rw-r--r-- 2 root root 6 Oct 19 14:30 testfile2 917513 -rw-r--r-- 2 root root 6 Oct 19 14:30 /tmp/link02
相对于链接目标文件的硬链接:
[root@Hisen ~]# ln ../Hisen/testdir1/testfile2 /tmp/link03 [root@Hisen ~]# ll -i /Hisen/testdir1/testfile2 /tmp/link03 917513 -rw-r--r-- 3 root root 6 Oct 19 14:30 /Hisen/testdir1/testfile2 917513 -rw-r--r-- 3 root root 6 Oct 19 14:30 /tmp/link03
软链接
软链接就相当于windows系统的快捷方式,它对被链接文件的依赖性非常强。软链接是一个全新的文件,被分配了一个不同于被链接文件的inode号,也就相当于软链接文件中保存的就是被链接文件的路径。如果按照存储中的路径找不到跟被链接文件相同文件名的文件,那么此软链接将会失效。言外之意就是,软链接并不关心被链接文件的具体内容,只要按照路径查找能匹配到相同文件名就好。软链接的优势在于它能跨分区跨设备甚至跨网络。
命令:ln -s filename [linkname]
[root@Hisen ~]# ln -s /Hisen/testdir1/testfile2 /tmp/link04 [root@Hisen ~]# ll -i /Hisen/testdir1/testfile2 /tmp/link04 917513 -rw-r--r-- 1 root root 6 Oct 19 14:30 /Hisen/testdir1/testfile2 393362 lrwxrwxrwx 1 root root 25 Oct 19 15:16 /tmp/link04 -> /Hisen/testdir1/testfile2
由上例可看出,软链接与实际文件的差别挺大的。/tmp/link04文件有25字节大小,具体内容为真实文件的路径,不信自己数一数。
将/Hisen/testdir1/testfile2文件删除后,软链接就呈现失效的状态。
那么在/Hisen/testdir1/下新建一个文件名为testfile2的文件会有什么效果呢?
软链接又恢复正常状态,印证了软链接并不关心文件里的具体内容。
另外,硬链接不能针对目录,那么软链接能否针对目录呢?
上图已经证实,软链接是可以针对于目录做链接。
我们已经知道,硬链接是无法跨设备跨分区的,那么软链接跨分区的效果如何?
正如所料到的那样,一切正常,证明软链接是可以跨设备跨分区的。
接下来,关于链接路径的写法,软链接和硬链接有着比较大的区别:
①当前目录下:
②绝对路径:
③相对于被链接文件路径的相对路径:
综上,软链接支持绝对路径和被链接文件路径相对的路径链接,但是由于在开发环境中考虑到可移植性,最好写成相对路径。
总结
通过上面两节对软链接和硬链接的介绍后,相信区别已经显而易见了。不过还是需要好好的总结一下:
1、命令格式:
硬链接:ln filename [linkname ]
软链接:ln -s filename [linkname]
2、inode:
硬链接:与被链接目标文件相同,创建时链接数递增;
软链接:与被链接目标文件不同,创建时目标文件inode引用计数不变。
3、依赖性:
硬链接:链接之后,与原名称无关,直接指向真实的数据。删除原文件名,不影响新文件名使用数据;
软链接:链接之后,需要能在保存的路径下匹配到相同的文件名。删除原文件名,则链接失效。
4、存储数据:
硬链接:直接指向真实的数据,相同的inode号;
软链接:存储的是被链接文件的路径。
5、跨设备跨分区:
硬链接:不可以;
软链接:可以。
6、链接路径:
硬链接:可当前、可绝对、可相对被链接文件路径;
软链接:不可当前、可绝对,可相对被链接文件路径。
7、链接对象:
硬链接:可文件、不可目录;
软链接:可文件、可目录。
原创文章,作者:Hisen,如若转载,请注明出处:http://www.178linux.com/53158