发现创建的符号链接删除不了,搜索才知道删除符号连接时文件名后面不能后缀一个/。比如:
[whb@jcwkyl test]$ ln -s ~whb
[whb@jcwkyl test]$ ls
whb
[whb@jcwkyl test]$ rm whb/
rm: cannot remove `whb/': Not a directory
[whb@jcwkyl test]$ rm -f whb/
rm: cannot remove `whb/': Not a directory
[whb@jcwkyl test]$ rm whb
[whb@jcwkyl test]$ ls
把硬连接和符号连接的概念再复习一下:
Unix下每个文件都有一个与之关联的数据结构用来描述该文件的信息,这个数据结构就是inode。
例如,创建一个文件:
[whb@jcwkyl test]$ ls
[whb@jcwkyl test]$ cat > testfile <<EOF
> This is just an example!
> EOF
testfile这个文件名就指向了一个inode数据结构,可以用stat命令查看这个inode的信息:
[whb@jcwkyl test]$ stat testfile
File: `testfile'
Size: 25 Blocks: 8 IO Block: 4096 regular file
Device: 802h/2050d Inode: 9306116 Links: 1
Access: (0664/-rw-rw-r--) Uid: ( 500/ whb) Gid: ( 500/ whb)
Access: 2010-01-06 16:16:27.000000000 +0800
Modify: 2010-01-06 16:16:27.000000000 +0800
Change: 2010-01-06 16:16:27.000000000 +0800
文件testfile的inode号是9306116。在GNU C中,可以用stat, fstat, lstat三个函数查看一个文件的信息,它们的区别在于如果查看的是一个符号连接文件,则lstat显示的是符号连接文件本身的信息,而fstat显示的是符号连接文件所指向的文件的信息。用fopen打开一个符号连接文件进行操作时,操作实际上是施加于符号连接文件所指向的文件的。
创建一个指向testfile文件的硬连接文件,意思就是创建一个文件名,这个文件名指向testfile所指向的那个inode。用link命令来创建一个硬连接文件:
[whb@jcwkyl test]$ link testfile hardlink
[whb@jcwkyl test]$ stat hardlink
File: `hardlink'
Size: 25 Blocks: 8 IO Block: 4096 regular file
Device: 802h/2050d Inode: 9306116 Links: 2
Access: (0664/-rw-rw-r--) Uid: ( 500/ whb) Gid: ( 500/ whb)
Access: 2010-01-06 16:16:27.000000000 +0800
Modify: 2010-01-06 16:16:27.000000000 +0800
Change: 2010-01-06 16:23:20.000000000 +0800
可以看到,hardlink文件的类型是regular file,它的inode号和testfile的inode号完全一样,它的Links是2,这是一个inode的引用计数。当删除hardlink或者删除testfile时,它的Links会减小为1,如果把剩下的那个文件再删掉,它的Links就成了0,此时操作系统就会把文件从磁盘上删除。
文件名相当于是一个指针,它指向一个inode,目录相当于是一个二级指针,它指向一个文件名列表。不能创建一个指向目录的硬连接。
创建一个硬连接也不等于复制文件。复制文件会在磁盘上做内容拷贝,创建硬连接只不过是创建一个指针。“复制文件”和“创建文件的硬连接”的共同点是都要求源文件必须存在。因此,不能跨文件系统或者跨分区创建硬连接。例如:
[whb@jcwkyl test]$ df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda3 49G 9.2G 37G 20% /
/dev/sda2 49G 11G 36G 24% /home
/dev/sda1 99M 19M 75M 21% /boot
tmpfs 1013M 0 1013M 0% /dev/shm
/dev/sda6 191G 36G 146G 20% /vm
看到我的/home是/dev/sda2,/boot在/dev/sda1上,创建一个/boot下某文件的硬连接:
[whb@jcwkyl test]$ link /boot/System.map-2.6.18-92.el5 map
link: cannot create link `map' to `/boot/System.map-2.6.18-92.el5': Invalid cross-device link
出错了,因为/dev/sda2上没有 System.map-2.6.18-92.el5 map文件。
同样,因为创建硬连接只是创建一个指针,所以硬连接不占磁盘空间。上面用stat命令查看testfile和hardlink两个文件,读取的是同一个inode的信息,所以大小自然一样,但是用du命令来查看,它会把指向同一个inode的多个硬连接文件自动只算一份:
[whb@jcwkyl test]$ du -hs *
4.0K hardlink
[whb@jcwkyl test]$ ls
hardlink testfile
再用一个例子来验证。在上面df -h的输出中能看到,/dev/sda6分区剩余146G空间,进入这个分区做个实验:
[whb@jcwkyl test]$ cd /vm
[whb@jcwkyl vm]$ du -hs *
5.1G centos.vdi
du: cannot read directory `lost+found': Permission denied
1.5G rh9img.vdi
54M share
8.1G vm1_clone.img
8.1G vm1_convert.img
987M vm1.vdi
936M vm2.vdi
937M vm3.vdi
1.6G winxp_slave.vdi
7.4G winxp.vdi
1.6G xen-images
看到winxp.vdi文件有7.4G,我们为这个文件创建100个硬连接:
[whb@jcwkyl vm]$ for ((i=1; i <= 100; i++)) ; do link winxp.vdi winxp.vdi_$i ; done
[whb@jcwkyl vm]$ ls
centos.vdi winxp.vdi_13 winxp.vdi_28 winxp.vdi_42 winxp.vdi_57 winxp.vdi_71 winxp.vdi_86
lost+found winxp.vdi_14 winxp.vdi_29 winxp.vdi_43 winxp.vdi_58 winxp.vdi_72 winxp.vdi_87
rh9img.vdi winxp.vdi_15 winxp.vdi_3 winxp.vdi_44 winxp.vdi_59 winxp.vdi_73 winxp.vdi_88
share winxp.vdi_16 winxp.vdi_30 winxp.vdi_45 winxp.vdi_6 winxp.vdi_74 winxp.vdi_89
vm1_clone.img winxp.vdi_17 winxp.vdi_31 winxp.vdi_46 winxp.vdi_60 winxp.vdi_75 winxp.vdi_9
vm1_convert.img winxp.vdi_18 winxp.vdi_32 winxp.vdi_47 winxp.vdi_61 winxp.vdi_76 winxp.vdi_90
vm1.vdi winxp.vdi_19 winxp.vdi_33 winxp.vdi_48 winxp.vdi_62 winxp.vdi_77 winxp.vdi_91
vm2.vdi winxp.vdi_2 winxp.vdi_34 winxp.vdi_49 winxp.vdi_63 winxp.vdi_78 winxp.vdi_92
vm3.vdi winxp.vdi_20 winxp.vdi_35 winxp.vdi_5 winxp.vdi_64 winxp.vdi_79 winxp.vdi_93
winxp_slave.vdi winxp.vdi_21 winxp.vdi_36 winxp.vdi_50 winxp.vdi_65 winxp.vdi_8 winxp.vdi_94
winxp.vdi winxp.vdi_22 winxp.vdi_37 winxp.vdi_51 winxp.vdi_66 winxp.vdi_80 winxp.vdi_95
winxp.vdi_1 winxp.vdi_23 winxp.vdi_38 winxp.vdi_52 winxp.vdi_67 winxp.vdi_81 winxp.vdi_96
winxp.vdi_10 winxp.vdi_24 winxp.vdi_39 winxp.vdi_53 winxp.vdi_68 winxp.vdi_82 winxp.vdi_97
winxp.vdi_100 winxp.vdi_25 winxp.vdi_4 winxp.vdi_54 winxp.vdi_69 winxp.vdi_83 winxp.vdi_98
winxp.vdi_11 winxp.vdi_26 winxp.vdi_40 winxp.vdi_55 winxp.vdi_7 winxp.vdi_84 winxp.vdi_99
winxp.vdi_12 winxp.vdi_27 winxp.vdi_41 winxp.vdi_56 winxp.vdi_70 winxp.vdi_85 xen-images
100个硬连接创建成功,用df命令查看分区空间使用情况,和刚才无异。如果是复制文件,不说速度,也早就报磁盘空间不足的异常了。
上面是硬连接。软连接也叫符号连接(symbolic link),它本身是一个独立的文件,指向一个新的inode,只不过在操作它时会识别出它是一个符号连接,从而所有操作都施加于它所指向的文件指向的inode上。例如:
[whb@jcwkyl test]$ ln -s testfile symboliclink
[whb@jcwkyl test]$ stat symboliclink
File: `symboliclink' -> `testfile'
Size: 8 Blocks: 0 IO Block: 4096 symbolic link
Device: 802h/2050d Inode: 9306117 Links: 1
Access: (0777/lrwxrwxrwx) Uid: ( 500/ whb) Gid: ( 500/ whb)
Access: 2010-01-06 16:45:14.000000000 +0800
Modify: 2010-01-06 16:45:09.000000000 +0800
Change: 2010-01-06 16:45:09.000000000 +0800
可以看到,它的文件类型是symbolic link,它的inode号是9306117(testfile和hardlink的inode号是9306116),它的Links是1。软连接不影响一个inode的引用计数。
总结如下:
软连接相当于一个快捷方式。
不能为目录创建硬连接,但可以为目录创建软连接。
不能跨文件系统或者跨分区创建硬连接,但可以创建软连接。