现在您已经知道关于文件的基本知识,该学些更加深入的东西了。
一个文件可以有超过一个的硬连接,就是说多个不同的文件名可以指向同一个文件(它们都和同一个资料结点需要结合)。但您不能做跨越文件系统的硬连接:所有的对某一个文件(资料结点)做直接参考必需在同一个文件系统上,这是因为每个文件系统都有它自己的一套资料结点,不同的文件系统间的资料结点序号可能会重复。
因为所有指向同一个资料结点的硬连接都是参照同一个文件,您可以用一个文件名来修改一个文件,用指向同一个资料结点但使用一个不同的文件名来查看您的更改结果。试一下这个:
所有的文件都是这样的──即使是像设备文件这样的特殊文件(例如 /dev/hda)。
一个目录只是一个文件名和资料结点序号的列表,也就是说是一个硬连接的列表。当您建立一个硬连接时,您只是在一个目录上加入了一个“文件名─序号”对。当您删除一个文件,您只是从目录中删除了一个硬连接。
到目前为止,我们隐藏了一个细节:Linux 核心把所有东西都看成是一个文件。这包括目录和各种设备,它们只是一些特殊的文件罢了。
您可能记得,ls -l 显示的第一个字符代表的是该文件的类型,对于一个普通的文件来说,这个字符就是个简单的 -。其它可能的字符包括一下:
因此一个硬连接是一个文件名和一个资料结点序号。一个文件其实是一个资料结点:在磁盘上的地址,文件类型,允许模式等等。一个符号连接是一个资料结点,它的内容包含一个硬连接的名字。一个符号连接把一个文件名和另外一个文件名配对,而一个硬连接把一个文件名和一个资料结点配对。
所有的指向同一个文件的硬连接有相同的形态,就是说任何一个跟其他的都是一样的,如果您在其中一个上面进行操作,其效果跟再其它的连接上进行操作是一样的。而在符号连接上的操作,有时候会影响这个符号连接自己的资料结点(含有硬连接名字的那个结点)的资料,有时候影响的是它指向的那个硬连接的内容。
符号连接和硬连接之间有几个重要的分别。
符号连接可以跨越文件系统,因为它们含有从根目录开始的完整的文件名,而所有的完整的文件名都是唯一的。但硬连接指向的是资料结点序号,资料结点序号仅仅在一个文件系统内是唯一的,如果不知道文件系统,则这个序号就会不明确。
您可以建立目录的符号连接,但不能建立目录的硬连接。每个目录都有它的硬连接──在它的母目录中以 . 列出,在它的所有子目录中以 .. 列出──但为了在文件系统中强制次序,不允许有其它的目录硬连接存在。因而一个目录中的文件数目等于该目录的所有硬连接的数目减 2 (减去目录名和 . 连接)。比较符号连接和硬连接,您只能跟一个存在的文件建立硬连接,因为它必需指向一个资料结点序号,但您可以把符号连接连到任何文件名,不论这个文件名的文件是否存在。
删除一个符号连接只删除这个连接,这对于连到的那个目标文件没有影响,而删除一个文件的最后的那个硬连接,则会把那个文件完全删除。
范例:
设备文件指向您的系统里的物理设备或者虚拟设备,例如您的硬盘、显卡、屏幕和键盘。虚拟设备则包括控制台 (console),以 /dev/console 来表示。
设备分为两种:字符式 (character) 和块式 (block)。字符设备可以每次访问一个字符,记住从这种设备中可以读取和写入的最小单位是一个字符(一个字节)。
块设备的存取必需以一个大的单位进行,我们叫作‘块’。一块里包含了一些字符。硬盘就是一个块设备。
您可以像对其它文件一样对设备文件进行读写,不过这些设备文件里可能含有一些您根本看不懂的乱七八糟的东西。一般来说往这些文件里随便写入数据不是什么好事儿,但又是却会有用,例如,您可以把一个 postscript 文件直接倾倒进打印机设备文件 /dev/lp0 或者把一些调制解调器 (modem) 指令传给相应的串连埠的设备文件。
/dev/null 是一个特殊的设备文件,您写入它的任何东西都会被丢弃。如果您不想要什么了,把它扔进 /dev/null。它基本上就是个无底深渊,如果您从 /dev/null 里读入,您立刻会得到一个文件结束 (EOF : end-of-file) 字符。/dev/zero 是另一个类似的设备文件,只是如果您从这里读取,您得到的是一个 \0
字符(这是一个空 (null) 字符,代表什么也不是,与数字 0 是不同的)。
一个管道是一个作用象个管道的文件。您放东西进这个文件,您放的东西从文件的另一端出来,因此它也叫 FIFO(First-In-First-Out 缩写,即先入先出),您放进去的第一个东西也是最先从另外一端出来的那个。
如果对一个具名的管道进行写入,这个写入的进程不到所有写入的资料被从管道中都读走了是不会结束的。如果您从一个管道中读取,读取进程会一直等到读到一些东西以后才结束。管道的大小总是 0:它不储存任何数据,它只是把两个进程连接起来,就像 shell 里的 | 一样。但是因为这个管道是有名字的,所以那两个被连的进程不需要总同一个命令行出现,它们甚至不需要是属于同一个用户的。
您可以试一下这个例子:
套接口 (sockets) 类似于管道 (pipes) 但它是在网络上面工作的。您到计算机就是靠它来做网络处理的。您可能听说过 ``Winsock'',那是 Windows 的套接口。
我们在这里不深入谈有关套接口,因为如果您不写程序,您不会用到它,但如果您看到您系统里有个文件类型是 s,您知道它是什么就行了。
Linux 的核心会建立一个特别的文件系统,在 Debian 系统上,这个文件系统加载于 /proc 目录下。这是一个“伪文件系统” (``pseudo-filesystem''),因为它不在任何一个物理设备上。
proc 文件系统包含系统和执行中的进程的资料。/proc 下的“文件”,有些是可以读懂的简单文本格式(试着键入 cat /proc/meminfo 或 cat /proc/cpuinfo),另外一些是一些神秘的数字组合。系统会有一些工具可以读取这些资料,然后翻译成一些您看的懂的东西。
有些人当看到一个特别的文件时常会觉得紧张,就是 /proc/kcore 文件。这个文件一般来说都很大,它是用来对核心进行除错用的。它其实根本不存在您的物理设备里(记住 /proc 下是一个伪文件系统),所以用不着担心它的大小。
如果您想知道所有关于 /proc 的资料,参看它的手册,键入man 5 proc。
有时候您会要把一个目录复制 (copy) 到另外一个地方,可能是因为您加了一个新硬盘,您要把您的 /usr/local 复制到它上面。有几个方法都可以达到这个目的。
第一个是用复制命令 cp。命令 cp -a 告诉 cp 在复制的时候,尽量保存可能保存的资料(这个 a 有 all 的意思)。因此,您可以用