ls 命令与链接文件
ls 是 list 单词的缩写。 ls 命令应该是 linux 命令中使用的最频繁的命令之一,从这一点也可以看出 linux 系统中文件概念的重要性。设备即文件也是在众多的 linux 书籍中被广泛引用的一句至理名言。
在 linux 终端中我们主要面向文件操作,在文件的读入、处理、输出中完成工作任务。我们使用 linux 下提供的众多实用程序,通过不同程序的组合来高效的完成所需操作。ls 命令作为最常使用的命令之一,也是通过对目录文件的操作来完成其功能的。在这里我们并不关心目录文件具体的存储或组织方式,我们只关心逻辑意义上的目录结构。下面是 ls 命令的一些具体实例:
- 不带任何参数的 ls 命令
[longyu@debian:16:59:41] tmp $ ls
fcitx-socket-:0
orbit-longyu
pulse-PKdhtXMmr18n
- ls -l 打印文件属性
[longyu@debian:16:55:14] ~ $ ls -l scons-man.pdf
-rw-r--r-- 1 longyu longyu 1700842 9月 18 17:25 scons-man.pdf
- ls -ld 打印目录属性
[longyu@debian:16:59:42] tmp $ ls -ld ./
drwxrwxrwt 17 root root 17408 10月 1 16:56 ./
- ls -la 打印所有文件(包含隐藏文件)
[longyu@debian:17:02:50] tmp $ ls -la
total 39
drwxrwxrwt 17 root root 17408 10月 1 16:56 .
drwxr-xr-x 26 root root 4096 9月 17 13:52 ..
...............................................
这里的 “.” 与 “..” 是相对路径表示方法。 . 表示当前目录,.. 表示上级目录。
- ls -i 显示 inode 号
[longyu@debian:21:16:36] / $ ls -i /
1703937 bin 12 initrd.img.old 524289 media 1179650 srv
............................................................................
ls -i 打印出文件的 -inode number ,这个 i-node number 在创建文件时由文件系统进行分配。-i 这个选项在基础的 linux 命令学习中并不常见。在学习软链接与硬链接时它能派上用场,能够让人直观的看到 inode 号。
下面就是 ls -i 的一个使用示例:
[longyu@debian:21:50:23] tmp $ touch test
[longyu@debian:21:50:26] tmp $ ls -i test
49 test
[longyu@debian:21:50:42] tmp $ ln test hardlink_test
[longyu@debian:21:50:57] tmp $ ls -i test hardlink_test
49 hardlink_test 49 test
longyu@debian:21:51:27] tmp $ ln -s /tmp/test softlink
[longyu@debian:21:51:41] tmp $ ls -i test softlink
54 softlink 49 test
上面的例子首先在当前目录下创建了一个名为 test 的文件,该文件的 i-node number 为 49。然后创建了 test 文件的一个硬链接,名为 hardlink_test。查看该文件的 i-node,你会发现该文件的 i-node与 test 文件相同。
当创建软链接时源文件与链接文件却拥有不同的 i-node值,这由软链接的原理决定。
i-node 与 block 是文件系统中涉及到的两个概念。i-node 一般用于存储大部分的与文件相关的属性息,block 一般仅用于存储文件的内容,这样就能够做到文件属性与内容的分离。
i-node 中保存的大部分与文件相关信息使得 i-node 成为访问文件的入口。这里所讲的文件可以笼统的划分为文件与目录,在目录的 block 中存储该目录中子目录及文件的信息。
当我们要访问某个目录下的某文件时,首先以根目录为起点,逐层遍历目录结构以获取该目录的 i-node number,以 i-node number 为 index 在文件系统中找到 i-node 中存储的对应 block 的位置。通过读取该 block 中的内容以文件名为标识获取到文件的 i-node number,再通过访问该 i-node number 指向的 i-node 来获取文件的起始 block 的位置,通过访问该 block 就能获取到文件的内容。
一般来说,一个文件只分配一个 i-node,某些情况下可以分配多个 i-node。每一个 i-node 都有一个链接计数器计数指向它的目录入口的数量。只有当这个计数器为 0 后,文件才能够被删除(释放与文件相关的 block)。
文件的删除其实就是一个解除链接的过程。当指向某个文件的目录入口数为 0,则无法从文件系统中找到该文件的 i-node number,也就无法访问文件。如果真的要删除文件,那么最好的方式是将文件所占用的 block 内容清空,但这种方式无疑会降低系统性能。
硬链接的创建原理
多个目录入口能够指向同一个 i-node,这是硬链接文件创建的基础。
以上面的例子来讲,创建一个 test 文件的硬链接时,仅仅在该文件的所在目录的 block 中添加了一个新的目录入口,该目录入口中保存的源文件名为 hardlink_test。对应的 i-node number 与 test 文件相同,同时将 test 文件的链接计数器加 1,这就完成了硬链接的创建。我们在上面的例子中可以看到新文件与原文件 ls -i 输出的 i-node number 相同。
由于 i-node number 指向同一个文件系统中的一个 i-node 节点,因此一个目录入口不能指向不同文件系统中的一个 i-node 节点。
软连接的创建原理
软链接弥补了硬链接的短处,它既能跨文件系统链接文件,也能让普通用户创建一个指向目录的链接,这由它的工作原理决定。
在上面的创建软链接的例子中,通过查看 softlink 文件,我们会得到如下信息:
[longyu@debian:23:13:09] tmp $ ln -s /tmp/test softlink
[longyu@debian:23:13:27] tmp $ ls -l softlink
lrwxrwxrwx 1 longyu longyu 9 10月 2 23:13 softlink -> /tmp/test
从 ls -l 信息的输出中可以发现,softlink 的内容就是指向文件的路径,softlink 文件的长度就是指向文件路径的长度。软链接不再以指向 i-node 的方式来完成文件的链接,它创建了一个独立的文件,文件的内容就是指向文件的路径,这就是软链接文件的 i-node number 与源文件不同的原因。
总结
本文以 linux 中 ls 命令的使用为入口,展示了文件操作在 linux 中的重要性。同时也借由 ls 命令的 -i 参数描述了链接文件的不同类型及创建的原理。