文件有文件名与数据,在linux中被分成用户数据(user data)和元数据(metadata)。用户数据即文件数据块,记录文件真实内容的地方,元数据是文件的附加属性,如文件大小、创建时间、所有者等信息。系统或程序通过inode号寻找正确的文件数据块。
在linux系统中查看inode可以使用stat或ls -i。
# stat /home/harris/source/glibc-2.16.0.tar.xz
File: `/home/harris/source/glibc-2.16.0.tar.xz'
Size: 9990512 Blocks: 19520 IO Block: 4096 regular file
Device: 807h/2055d Inode: 2485677 Links: 1
Access: (0600/-rw-------) Uid: ( 1000/ harris) Gid: ( 1000/ harris)
...
...
# mv /home/harris/source/glibc-2.16.0.tar.xz /home/harris/Desktop/glibc.tar.xz
# ls -i -F /home/harris/Desktop/glibc.tar.xz
2485677 /home/harris/Desktop/glibc.tar.xz
为解决文件的共享使用,linux系统引入了两种链接,硬链接hard link与软链接soft link。
若一个inode号对应多个文件,则称这些文件为硬链接。硬链接特性:
1 文件有相同的inode及data block
2 只能对已存在的文件进行创建
3 不能交叉文件系统进行硬链接的创建
4 不能对目录进行创建,只可对文件创建
5 删除一个硬链接文件并不影响其他有相同inode号的文件
# ls -li
total 0
// 只能对已存在的文件创建硬连接
# link old.file hard.link
link: cannot create link `hard.link' to `old.file': No such file or directory
# echo "This is an original file" > old.file
# cat old.file
This is an original file
# stat old.file
File: `old.file'
Size: 25 Blocks: 8 IO Block: 4096 regular file
Device: 807h/2055d Inode: 660650 Links: 2
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
...
// 文件有相同的 inode 号以及 data block
# link old.file hard.link ; ls -li
total 8
660650 -rw-r--r-- 2 root root 25 Sep 1 17:44 hard.link
660650 -rw-r--r-- 2 root root 25 Sep 1 17:44 old.file
// 不能交叉文件系统
# ln /dev/input/event5 /root/bfile.txt
ln: failed to create hard link `/root/bfile.txt' => `/dev/input/event5':
Invalid cross-device link
// 不能对目录进行创建硬连接
# mkdir -p old.dir/test
# ln old.dir/ hardlink.dir
ln: `old.dir/': hard link not allowed for directory
# ls -iF
660650 hard.link 657948 old.dir/ 660650 old.file
inode号在各文件系统下是唯一的,当linux挂载多个文件系统后将出现inode号重复的现象,因此硬链接不可跨文件系统,使用df命令可查看当前系统中挂载的文件系统类型,各文件inode使用情况及文件系统挂载点。
# df -i --print-type
Filesystem Type Inodes IUsed IFree IUse% Mounted on
/dev/sda7 ext4 3147760 283483 2864277 10% /
udev devtmpfs 496088 553 495535 1% /dev
tmpfs tmpfs 499006 491 498515 1% /run
none tmpfs 499006 3 499003 1% /run/lock
none tmpfs 499006 15 498991 1% /run/shm
/dev/sda6 fuseblk 74383900 4786 74379114 1% /media/DiskE
/dev/sda8 fuseblk 29524592 19939 29504653 1% /media/DiskF
硬链接不能对目录创建是受限于文件系统的设计,现linux文件系统中的目录均隐藏了两个特殊的目录:当前目录.与父目录..,查看这两个特殊目录的inode号可知其实这两个目录就是两个硬链接。若系统允许对目录创建硬链接则会产生目录环。
软链接与硬链接不同,若文件用户数据块中存放的内容是另一文件的路径名的指向,则该文件就是软链接。软链接就是一个普通文件,只是数据块内容有点特殊。软链接有着自己的ionde及用户数据块。
1 软链接有自己的文件属性及权限等
2 可对不存在的文件或目录创建软链接
3 软链接可交叉文件系统
4 软链接可对文件或目录创建
5 创建软链接时,链接指数i_nlink不会增加
6 删除软链接并不会影响被指向的文件,但若被指向的原文件被删除,则相关软链接被称为死链接(dangling link,若被指向路径文件被重新创建,死链接可恢复为正常的软链接)
# ls -li
total 0
// 可对不存在的文件创建软链接
# ln -s old.file soft.link
# ls -liF
total 0
789467 lrwxrwxrwx 1 root root 8 Sep 1 18:00 soft.link -> old.file
// 由于被指向的文件不存在,此时的软链接 soft.link 就是死链接
# cat soft.link
cat: soft.link: No such file or directory
// 创建被指向的文件 old.file,soft.link 恢复成正常的软链接
# echo "This is an original file_A" >> old.file
# cat soft.link
This is an original file_A
软链接的用户数据也可以是另一个软链接的路径,其解析过程是递归的,需注意:软链接创建时原文件的路径指向使用绝对路径较好。使用相对路径创建的软链接被移动后该软链接文件将成为一个死链接,因为链接数据块中记录的亦是相对路径指向。
链接相关命令
在linux中查看当前系统已挂载的文件系统类型,除上述使用的命令df,还可使用命令mount或查看文件/proc/mounts
使用find查找软链接与硬链接
// 查找在路径 /home 下的文件 data.txt 的软链接
# find /home -lname data.txt
/home/harris/debug/test2/a
// 查看路径 /home 有相同 inode 的所有硬链接
# find /home -samefile /home/harris/debug/test3/old.file
/home/harris/debug/test3/hard.link
/home/harris/debug/test3/old.file
# find /home -inum 660650
/home/harris/debug/test3/hard.link
/home/harris/debug/test3/old.file
// 列出路径 /home/harris/debug/ 下的所有软链接文件
# find /home/harris/debug/ -type l -ls
656662 0 lrwxrwxrwx 1 harris harris 1 Sep 1 14:37 /home/harris/debug/test2/b -> a
656627 0 lrwxrwxrwx 1 harris harris 8 Sep 1 14:37 /home/harris/debug/test2/a ->
data.txt
789467 0 lrwxrwxrwx 1 root root 8 Sep 1 18:00 /home/harris/debug/test/soft.link ->
old.file
789496 0 lrwxrwxrwx 1 root root 7 Sep 1 18:01
/home/harris/debug/test/soft.link.dir -> old.dir
系统根据磁盘大小默认设定了inode的值,若有必要,可在格式文件系统前对该值进行修改,如键入命令 mkfs -t ext4 -I 512/dev/sda4,将/dev/sda4格式成inode大小是512字节的ext4文件系统。
查看系统的inode值
// 查看磁盘分区 /dev/sda7 上的 inode 值
# dumpe2fs -h /dev/sda7 | grep "Inode size"
dumpe2fs 1.42 (29-Nov-2011)
Inode size: 256
# tune2fs -l /dev/sda7 | grep "Inode size"
Inode size: 256