在学习和创建软链接遇到了一点问题,总结一下:
在当前文件夹下面建立了两个临时文件夹tempdir1和tempdir2,然后在tempdir2里面创建了一个hello文件,然后用指令ln -s tempdir2/hello tempdir1/soft-hello-link在tempdir1目录下创建一个软链接,用tree指令来查看一下当前目录树结构:
用ls -l命令来查看一下soft-hello-link文件,可以发现文件权限的第一个是l,表示这是一个链接文件。
查看里面的内容,这时候发现tempdir2里面的hello可以查看,但是tempdir1里面的soft-hello-link显示没有那个文件或目录,我进入tempdir1查看了一下soft-hello-link,意识到这可能是绝对地址的问题,也就是说进行软链接的时候要把绝对地址用上,而现在tempdir1里面的soft-hello-link->tempdir2/hello,根据软链接的特性,应该是在目录树中找tempdir2/hello,而实际上的绝对地址应该是/home/carl/OSExam/E4/tempdir2/hello,自然是查找不到的,为了验证我的想法,我重新在tempdir1中链接了一个不存在的文件,果然,也会链接成功也会显示这个文件是个链接:
当我在tempdir1和tempdir2的父目录中尝试指令ln -s ./tempdir2/hello tempdir1/soft-hello-link的时候,我以为在shell里面,会把./tempdir2/soft-hello-link解释成绝对路径的时候,发现ln命令只是单纯地把第二个参数的文本复制过去,既不会检查这个文件是否真实存在,也不会对文件的路径进行解析。
最后,我利用绝对路径,终于是正常的了,而且这时候这个链接文件显示颜色是蓝色,证明正常情况下软链接的文件应该是蓝色,而存在错误(链接指向的文件不存在)则是显示红色,背景也会加深(看来图形界面的256色还是要比字符模式的16色要方便一点点呀)。此时访问也可以正常显示内容了。
软链接之所以会出现上面的情况,是因为软链接是重新创建了一个文件(inode号都不一样),而这个文件里面存了相应文件的路径,所以他是通过文件的访问名称来原来的文件的。由于是新创建的文件,所以并不会检查文件是否存在,也就不会把文件的路径转化为绝对路径了。而硬链接,实际上给指向文件是在目录树中不同位置的添加了一个新的名称标识,它与原来目录的地位是相同的,我们用ls -i来查看两个目录项所对应的索引节点号是相同的:
因此,由于是指向目录树中的某个存在的文件,硬链接实际上是会进行文件检查的,比如我对tempdir1和tempdir2的父目录中不存在的文件s进行一个硬链接:ln s tempdir1/hard-link ,这条指令是不会像软链接一样执行成功的,实惠报错的:
用tree指令来观察一下建立硬链接后目录数的层次结构:
由于硬链接是对某个文件在目录树中不同位置增加一个新的名称标识而已,所以inode号是一样的,文件的访问权限也是一样的,就是同一个文件,可以通过ls指令来观察硬链接和原文件的相关信息,stat命令用于输出文件的inode储存的文件元信息(metadata),可以看到这包括文件的字节数、文件的用户ID、文件的组ID、文件的权限、文件的时间戳(包括最近访问时间(指读取文件内容)、最近更改时间(指更改文件内容)、最近改动时间(指更改文件状态,比如权限等),但是不同于windows,linux没有记录创建时间)、硬链接的数目、文件类型、设备号、inode所使用的block数、文件数举block的位置等等,这里的硬链接数目是2:
而我们再查看刚刚软链接的信息,会发现是另外一个新文件的信息,inode都不一样,文件的权限也不一样:
从上面的图我们可以看到软链接的文件大小为36,为什么是36呢?原因就是软链接其实存放这的是内容是指向文件的路径,这里是“/home/carl/OSExams/E4/tempdir2/hello”,不多不少,刚好36。而原文件hello和硬链接的大小为11,那是因为里面存放了“hello dir2”,我一看,这明明只有10个字符啊,也没有换行(我使用echo hello dir2 > hello进行创建的),这也不是c语言应该不是字符结束符'\0',那肯定是有什么特殊符号我看不到的。然后打开vim,输入:set list查看hello的特殊字符($表示换行符,^I表示tab制表符),发现末尾竟然有一个换行符$:
上网百度了一下,发现在创建一个文件的时候(ps:这里我只实验通过vim、gedit方式创建),linux系统会确保最后一个字符是换行符!而通过echo来创建文件的话,也会在末尾自动添加一个换行符,原因是echo默认输出完就换行的,可以通过echo来验证,通过命令行提示符我们可以看出echo输出确实会换行:
而如果echo指令带上参数-n,则就不会换行:
因此,如果想要创建一个末尾没有换行符的文件的时候,比如“hello dir2”我就是想要纯粹的“hello dir2”我并不想系统末尾帮我保存一个换行符,我可以通过这种方式进行创建:
可是奇怪的是,我用vim打开hello-file的时候,输入:set list还是能发现最后有个换行符$(查了一下好象是因为vi会确保文件的最后一个符号一定是换行符,所以会显示出来):
我以为只要用vim打开以后再保存就会显示换行符了,可是并没有,大小依然是10,cat查看也不会输出换行,这大概是系统检测到我没有进行任何操作,所以保存了也不会对硬盘中的文件进行任何修改:
但是,我一旦用gedit打开,打开以后马上按保存,系统就已经在末尾自动添加一个换行符了,和vim不同:
好了,这不是关键,只是好奇乱看了一下啊而已,回到原来的硬链接和软链接。对于硬链接,如果删除了原文件,只会在inode记录的元信息中的硬链接数-1,直到所有硬链接都删除了(硬链接数为0)对应的磁盘上的文件才会被删除;而对于软链接,如果把原文件删除了,则无法进行访问了,而且会显示链接文件是错误的(红色字体,背景加深):
这时候,只要在tempdir2中对tempdir1的硬链接文件再进行一个硬链接,tempdir1中的软链接也会恢复正常:
过程查了一下相关知识,把看到的觉得不错的文章记录下来。
1. Inode
在Linux系统中,每个文件都有一个inode(索引节点),inode存储了文件的元信息,主要有:
*文件的字节数
*文件的用户ID
*文件的组ID
*文件的read,write,execute权限
*文件的时间戳:最近的产生时间,最近一次存取时间,最近一次修改时间
*链接数
*inode所使用的block数
*文件数据block的位置
等等
这里补充一点,文件是存储在硬盘上的。硬盘的最小存储单位是扇区(Sector),每 个扇区存储512字节。出于效率的考虑,操作系统不是按一个扇区一个扇区的读取文件,而是一次连续读取多个扇区,通常被称作块(block)。块是文件存 取的最小单位,一般为4K,即连续的8个扇区组成一个块。因为inode要存储文件的元信息,它也会消耗硬盘空间,一般是128或256字节。inode 节点的总数,在硬盘格式化的时候就给定了,一般是每1KB或2KB设置一个inode。有时候会遇到剩余硬盘空间足够,但系统仍然提示空间不足的情况,其 原因就是inode用完了。
Linux系统中每个文件都有文件名,但是操作系统并不是按文件名来识别文件,而是按 inode号来识别不同的文件。当用户打开一个文件时,主要有3步:1. 系统找到文件名对应的inode号;2. 通过inode号获取inode信息;3. 根据inode信息找到文件所在的block并读取数据。另外,因为系统是按inode来识别文件,所以直接删除inode就能到达删除文件的作用。
在Linux中有“一切皆文件”的说法,目录也被看作一种文件。当创建目录时,一般会生成两个目录项:“.”和“..”。可以看成是两个硬链接,前者的inode号就是当前目录的inode 号;后者的inode号就是当前目录的父目录的inode号。
<附>
查看inode信息的方法:
---
stat 文件名
---
查看inode号的方法:
---
ls -i 文件名
---
查看硬盘分区的inode总数和已使用inode的数量:
---
df -i
---
2. 硬链接和软链接
1)硬链接(hard link)
硬链接打破了文件名和inode号“一一对应”的关系,实现让多个文件名指向同一个inode号。删除其中一个文件名,不影响另一个文件名的访问。硬链接生成的文件大小与原文件一样大。创建硬链接的方法如下:
---
ln 源文件 目标文件
---
每当创建一个硬链接,inode信息里记录的链接数就会加1;反之,删除一个文件名,链接数就会减1。当链接数为0时,说明没有文件指向该inode,系统将回收该inode号,以及所对应的block区域。
2)软链接(soft link)
软链接又叫符号链接(symbolic link)。软链接生成的文件是对源文件的引用,但是与原文件的inode号不同。访问软链接生成的文件时,其实是读取的源文件。当源文件被删除时,系统会提示找不到文件的错误信息。可以用如下方法创建软链接:
---
ln -s 源文件 目标文件
---
3)比较
*硬链接指向源文件索引节点,不重新分配inode;软链接生成时分配新的inode
*硬链接文件大小与源文件大小相同;软链接文件大小与源文件不同,一般较小
*硬链接不能跨越文件系统;软链接可以
*一般情况下,不能为目录创建硬链接;但可以为目录创建软链接
转自: