回到Linux基础系列文章大纲
回到Shell系列文章大纲


Linux中绝对路径的表示方式为什么是”/usr”而不是”//usr”

今天闲逛贴吧,竟然看到有个人问绝对路径的表示方式为什么不是//usr/local而是/usr/local。原文:

我想99%的人都没想过这个问题,都理所当然的认为:它不就是根”/“吗?

很巧,我是个探索狂和强迫症患者,当年回炉复习文件系统的时候,正好琢磨过这个问题。下面是我的理解,但本人毕竟菜鸟,也没法验证是否真是如此,如有错误,欢迎大牛指正。

我的结论是://usr/local是正确的,和/usr/local的意义完全相同。

1.根文件系统具有”自引用”性,”/“和”//“无论是功能上还是意义上,都完全相同。

2.除了根目录外的任意目录,其内的”.”和”..”的inode号不一致,它们分别是当前目录的硬链接和父目录的硬链接。但是根目录下的”.”和”..”的inode号一致,都是根目录的硬链接。

例如:

1
2
3
4
5
6
7
8
9
[root@node1 ~]# ls -ail /usr
total 204
155 drwxr-xr-x. 13 root root 4096 May 11 2017 .
128 dr-xr-xr-x. 17 root root 4096 May 11 2017 ..

[root@node1 ~]# ls -ail /
total 36
128 dr-xr-xr-x. 17 root root 4096 May 11 2017 .
128 dr-xr-xr-x. 17 root root 4096 May 11 2017 ..

3.在Linux操作系统启动的时候,内核先有”虚拟根文件系统”,表示方法为”/“,之后找到真实的根文件系统,从”虚拟跟文件系统”切换到”真实根文件系统”。切换的方式就是将真实的根文件系统”挂载”到虚拟根文件系统上(并非真的挂载,但可以这么理解)。所以到这里正确的方式是”//“,其中第一个”/“是虚拟根目录,第二个”/“是真实根文件系统。

因此,根文件系统下的”..”代表的是第一个”/“,即虚根,”.”代表的是第二个”/“,代表的是真实根目录。

在切换到真实根文件系统时,虚根和实根的inode号是一致的。但为什么能一致?虚根为什么也有inode号?

这是因为在每个分区创建为文件系统的时候,一定会预先保留几个特殊的inode号,相同的文件系统,这些预留inode号一定是相同的。例如ext类的文件系统中,为”/“保留的inode号为2,为”/proc”保留的inode号为1。这些预留的inode号就是为了给切换到真实根文件系统前的虚拟根文件系统使用的,它们记录在initrd/initramfs中。这样一来,既能为虚根分配inode,又能保证在切换时,”/“(虚根)和”//“(实根)的inode号保持一致,并在系统成功启动后使用。

之所以可以使用”/“来代替”//“,也许是为了方便,也许是为了某些一致性,谁知道呢,甚至上面我的理解也是错误的呢。此外,除了绝对路径的前缀”/“,路径中的任意”/“都可以替换为”//“,例如”/usr//local”也能正确表示”/usr/local”,但它们和前缀的”//“意义不同,之所以不报错且能正确当成单个斜线/,是因为系统有专门的路径处理函数。