一旦你拥有了一个toolchain,就拥有了制作MagicLinux的初级武器了。
这个时候你可能已经开始辂胳膊挽袖子,准备大干一场了,可你却突然发现,
还是什么也做不了,原因就在于你还不了解如何使用toolchain来制作MagicLinux。下
一章我将讲述Linux的组织结构,让你对Linux有一个彻底的了解,为正式开始制作
MagicLinux作准备。
第二章 Linux的文件组织结构
像Linux这些类Unix操作系统与你所熟知的Windows有很大的不同,其中一个显著
的不同就是类Unix操作系统的文件管理方式,它只有一个文件树,以一个树根“/”
为起点,所有的文件和外部设备都以文件的形式挂接在这个文件树上,包括硬盘、
软驱、光驱、调制解调器等,而且有着非常严格的组织结构。不同的Unix分支在文
件组织细节方面会有一些不同,但基本层次与本文下面将介绍的内容是相一致的。
在Linux操作系统下,众多软件都被安装在既定的位置,它们的文件名、文件内
容、目录结构等都是固定的,相互合作的软件系统通过这些既定的规则就可以恰当
的找到它们的合作伙伴,互相配合完成一些更为复杂的任务。作为用户也可以在通
过查看既定的位置的内容来判断是否安装了自己需要的软件,或者修改软件的配置
等,且同等的操作在任何同类系统中都能得到相同的结果。为了实现这些目的,
Linux必须严格的组织文件层次关系,且形成一种规范行为,才不至于因为混乱而使
得用户以及软件系统对操作系统产生恐慌。这充分体现了Unix的传统——简单。
Magic Linux作为一个成熟的Linux发布,必定要因袭传统标准,作为Magic Linux的
开发者,熟识Linux的文件组织结构也很自然的成为你必修的基本功课,因为这决定
了你制作出来的系统能否被其他人所接受,以及能否正确运行那些成熟稳定且应用
广泛的软件产品。
2.1 基本组织原则
类Unix系统的文件组织结构是按照一个基本组织原则而设计的。当你能够深入
理解这些原则之后,你会发现目前这种组织结构是必然的选择,你也不必牢记那些
结构性的问题,而不由自主的做出与现今沿袭下来的基本一致的布局来。
按照各文件在系统中所起的作用,可以划分为是否共享与是否可变两类属性。
一般来说,不一定需要本地系统提供的文件都可以看作为共享的,而那些必须由本
地系统提供的文件则可以看作为非共享的;能够被保存在只读存储设备上的文件都
可以被认为是不可变的,反之那些必须要存在可读写存储设备上的文件就是可变
的。
从是否可共享这一属性上可以充分体现类Unix操作系统极强的灵活性与可扩展
性。由于采用单一文件树形式,任何设备都能够以文件方式挂接到树的某一枝上,
这使得非本地存储设备通过某种网络协议挂接到本地文件树上成为可能。这样,很
有可能你正在使用的某些程序根本就不在你的计算机里,而是在离你非常遥远的大
洋彼岸。给文件赋予是否可共享这一属性,使得这种操作变得轻松且合理,只要按
照这个原则来组织文件布局,就可以很容易的提供这种让你难以置信的强大功能。
其实这也是历史原因造成的,毕竟在很早以前,大量的本地存储是非常奢侈的事
情,让远端的一个设备来存储大家共用的一些程序是很棒的解决方案。那些程序自
然的就是为大家所共享的。然而这种共享不能解决所有问题,毕竟本机的设备不能
完全与别人的设备相同,那么它们对应的文件也不能提供给别人使用,自然的也就
是非共享文件了。
可变属性在某种意义上为类Unix系统提供了很大的伸缩性,可以容易的将它们
一直到很多非通用设备上,比如电视机顶盒。它允许你合理的将那些固定不变的二
进制代码存储在只读设备上,而那些随着系统运行而时刻变化的内容,如系统日志
等可以存储在随机读写设备上,这样便于你最大限度的节省硬件设备上的成本开
销。于此,系统的安全性也得到了保障,毕竟很少有人希望他们那些常用的程序可
以很容易的被一些恶意程序所修改,这点Windows上的用户们是感同身受的。
以前,类Unix系统的文件组织结构不是非常清晰,/usr和/etc目录混合着大量的可
变与不可变的文件。由此,引入了/var目录,将/usr目录下的可变文件全部转移至/var
目录下,这就保证了/usr目录可以单独放在其他设备上且以只读方式被挂接在树根
上。目前/etc目录下的可变文件还没有完全转移至/var目录下,但是从技术角度看,
这也只是一个时间问题。
下表列出了依照这一基本原则组织文件的典型例子:
|
可共享 |
不可共享 |
不可变 |
/usr |
/etc |
/opt |
/boot |
|
可变 |
/var/mail |
/var/run |
/var/spool/news |
/var/lock |
表2-1
2.2 根文件系统
根文件系统保存在根分区,它担负着系统启动、修复、更新、恢复等重要任
务。当你启动系统成功后,可以执行下列命令查看树根的内容:
#cd /
#ls
结果可能是下面的内容:
bin dev lib media opt root sys tmp usr |
虽然他们井然有序的排列在一起,但是他们并不一定完全存放在同一个设备上,比
如/usr、/var等,而且/sys和/proc根本不在任何外部存储设备上,而是在内存中。
这里,将直接挂接在树根“/”上的设备叫做根设备,可能是内存,也可能是磁
盘,如果是磁盘的某一分区,就称之为根分区,它是操作系统启动时默认挂接的设
备,是所有文件系统的根源。可谓有了根文件系统就有了一切。如果当系统崩溃到
连根文件系统都无法挂接时,你只有唯一的选择——重装。
为了启动系统,根分区的内容必须能够支持到系统挂接了其他设备和其它磁盘
分区之后。这就要求它必须包含必要的工具(如init、mount等),配置信息(如
inittab、fstab等)以及其他重要的启动数据。还应该包含引导器的配置信息,但与具
体引导器的不同而不同,有的需要有的可以放在其他地方。
为了更新或修复系统,根文件系统还包含那些能够提供这些功能的工具。保证
有经验的系统管理员能够重建被毁坏的部分。
为了恢复系统,根文件系统要提供备份和还原工具,在必要的时候可以通过以
前的备份恢复系统的运行。这些备份往往保存在光盘、磁带等大容量外存上面。
根文件系统上的内容需要平衡考虑,要仔细斟酌将哪些内容放入根分区,尽量
保证根分区的精巧。有很多因素要求跟分区要尽量的精巧:第一,根文件系统包含
了众多的系统特有的配置文件,如:内核、hostname文件等,这些都是系统特有的,
这就意味着根文件系统不能通过网络系统共享。保证网络系统根分区在服务器的最
小化,可以最小化非共享文件区域 的磁盘空间浪费。这也使得工作站可以使用更小
容量的硬盘。第二,虽然你划分了较大的根分区给根文件系统,且对它付诸了你的
心血,可是有人却使用了更小的根分区,导致你的发布无法安装。当系统有了更多
的安装文件,你可能会发现这与其它使用更小根分区的系统不兼容了。作为开发
者,你就把这个问题转移给你的广大用户了。第三,由于磁盘错误毁坏了根分区数
据是致命的,更小的根分区可以尽量减小这种致命问题的发生。
应用程序不得创建或依赖根文件系统上的特定文件或子目录,后面将要讲述的
其他位置可以为任何软件包提供更多的灵活性。这有很多原因,最主要的,从性能
或安全等多方面考量,系统管理员需要保证根文件系统精小,而且也规避了因交叉
挂接而引发的各种混乱问题。
根文件系统必须包含下列目录,某些可以是符号连接:
名称 |
功能 |
bin |
重要的可执行文件,shell命令 |
boot |
引导器配置文件,内核等。 |
dev |
设备文件 |
etc |
系统专有配置文件 |
lib |
重要的共享库和内核模块 |
media |
可移动设备挂接点 |
mnt |
其他文件系统的临时挂接点 |
opt |
附加应用软件包 |
sbin |
重要的系统可执行文件 |
srv |
本系统提供的用于服务器的数据 |
tmp |
临时文件 |
usr |
文件系统的第二层 |
var |
可变数据 |
表2-2-1
这些内容可能与你理解的不太一样,但这就是全部必须的内容,各目录的详细内容
下面会逐一介绍。而下表所列的可能就是你疑问的了,但这些是可选的,只要在有
相应子系统的时候才需要。不过对于大多数通用系统它们都是需要的。
名称 |
功能 |
home |
用户自己的目录 |
lib |
其他各式的重要共享库,比较少见 |
root |
root用户的专有目录 |
表2-2-2
它们的具体内容也会在下面内容进行详细介绍。
2.3 子目录
本节将讲述根文件系统下各子目的详细内容,以及为了使系统能够运行它们所必
须包含的内容。/usr和/var由于本身的复杂性,我会以单独的章节介绍它们。
2.3.1 /bin
/bin目录下包含了用户命令文件,也就是shell命令,供所有用户使用。不仅仅是
用户,脚本程序也要使用它们。即使其他文件系统还没有被挂接时,它们也要能够
工作。
/bin目录不得包含任何子目录,下表列出了它必有的内容,有些文件可能是一个符号连接:
名称 |
功能 |
cat |
连接多个文件,并将内容输出至标准输出 |
chgrp |
改变文件的所属组 |
chmod |
改变文件的访问权限 |
chown |
改变文件的所属用户和组 |
cp |
复制文件和目录 |
date |
打印或设置系统日期与时间 |
dd |
转换并复制文件 |
df |
查看文件系统磁盘空间使用情况 |
dmesg |
打印或控制内核的消息缓冲 |
echo |
显示一行文本 |
false |
不做任何事情,表示不成功 |
hostname |
显示或设置系统的主机名 |
kill |
向进程发送信号 |
ln |
创建文件连接 |
login |
开始系统上的一个会话 |
ls |
列出目录内容 |
mkdir |
创建目录 |
mknod |
创建块或字符设备的专用文件 |
more |
分页显示文本 |
mount |
挂接一个文件系统 |
mv |
移动文件或更改文件名 |
ps |
查看系统进程状态 |
pwd |
打印当前工作目录名 |
rm |
删除文件或目录 |
rmdir |
删除空目录 |
sed |
一个流式文本编辑器 |
sh |
Bourne命令shell |
stty |
改变或打印终端行设置 |
su |
改变用户标识 |
sync |
刷新文件系统缓存 |
true |
什么也不做,表示成功 |
umount |
卸载文件系统 |
uname |
打印系统信息 |
表2-3-1
如果/bin/sh不是真正的Bourne shell,它必须连接到一个真正的shell命令上,既可以是
硬连接也可以是软连接。例如,调用sh或bash时,bash会有不同的行为。使用符号连
接也使得用户容易地了解到/bin/sh不是一个真正的Bourne shell。“[”和“test”命令
必须被放在一起,既可以在/bin目录下也可以在/usr/bin目录下。这是为了保持与
POSIX.2标准一致,即使它们已经由shell程序内部实现了。
下表的内容是可选的。如果有相应的子系统被安装,则是必须的。目前大多数
发布都会部分的提供它们。
名称 |
功能 |
csh |
著名的C shell |
ed |
“ed”文本编辑器 |
tar |
tar打包工具 |
cpio |
cpio打包工具 |
gzip |
GNU压缩工具 |
gunzip |
GNU解压缩工具 |
zcat |
GNU解压缩工具 |
netstat |
网络统计工具 |
ping |
ICMP网络测试工具 |
表2-3-2
如果存在gunzip和zcat程序,它们一定是gzip的软连接或硬连接。/bin/csh可能是/bin/tcsh
或/usr/bin/tcsh的符号连接。tar、gzip和cpio为系统提供了恢复能力,反之,如果不考虑
从根分区恢复系统的话,这些程序可被忽略(例如一个只读片内根系统,通过NFS
挂接/usr目录)。若要通过网络恢复系统,还需要ftp或tftp存在于根分区。
2.3.2 /boot
该目录包含了除在启动时刻和映像安装器不需要的配置文件外,启动进程所需
要的所有内容。换句话说,/boot目录下存储的数据用于内核开始执行用户级程序之
前的操作。这里也可能包含备份的主引导扇区信息和扇区映像文件。另外,操作系
统的内核必须放在“/”或“/boot”目录下。
2.3.3 /dev
/dev目录是设备文件或专有文件的存放位置。要是/dev中的设备需要手工创
建,/dev必须含有一个名为MAKEDEV的命令,它能够创建需要的设备文件。同时也
应该为任何本地设备包含一个MAKEDEV.local文件。如果需要,MAKEDEV必须具备
为任何发现与系统的设备创建文件的权限,而不限于那些特定的安装实现。
2.3.4 /etc
/etc包含了系统特有的配置文件。所谓配置文件,就是用于控制程序运行的本地
文件,它一定是不可变文件,而且是可编辑的,那些二进制可执行文件是不能作为
配置文件的。/etc下基本没有二进制文件,下表中列出的目录需要包含在/etc下,有
些可能是符号连接。
名称 |
功能 |
opt |
/opt目录下各软件的配置文件 |
X11 |
X Window系统的配置文件,可选。 |
sgml |
SGML的配置文件,可选。 |
xml |
XML的配置文件,可选。 |
表2-3-3
当相关子系统安装后,下列文件必须放在/etc中,有些也可以是符号连接:
名称 |
功能 |
csh.login |
C shell登陆的全局初始化文件,有C shell时有效。 |
exports |
NFS文件系统的访问控制列表,有NFS支持时有效。 |
fstab |
文件系统的静态信息,系统初始化时需要挂接多个文件系统时需要。 |
ftpusers |
FTP守护进程的用户访问控制列表。 |
geteways |
routed的网关列表。 |
gettydefs |
getty程序的配置文件。 |
group |
用户组列表文件。 |
host.conf |
决定如何解析域名。 |
hosts |
主机名静态信息。 |
hosts.allow |
允许访问本机的IP地址列表。 |
hosts.deny |
禁止访问本机的IP地址列表。冲突时,优先。 |
hosts.equiv |
信任主机列表,作用于rlogin,rsh,rcp。 |
hosts.lpd |
信任主机列表,作用于lpd。 |
inetd.conf |
inetd守护进程的配置文件。 |
inittab |
init程序的配置文件。 |
issue |
登陆提示符上面的消息和标识文件。 |
ld.so.conf |
搜索共享库的目录列表文件。 |
motd |
本机的标识信息,远程登陆时确认你当前控制的是本机还是远程计算机。 |
mtab |
文件系统的动态信息,记录当前挂载的文件系统。 |
mtools.conf |
mtools程序的配置文件。 |
networks |
网络名称的静态信息,与hosts类似。 |
passwd |
用户密码文件。 |
printcap |
ldp打印机的性能数据库。 |
profile |
sh shell登陆的全局初始化文件。 |
protocols |
网络协议定义文件。 |
resolv.conf |
DNS域名解析的配置文件。 |
rpc |
RPC协议定义文件。 |
securetty |
Root登陆的TTY访问控制文件。 |
services |
记录网络服务名和它们对应使用的端口号及协议。 |
shells |
可使用的登陆shell路径名。 |
syslog.conf |
syslogd守护进程的配置文件。 |
表2-3-4
这里,显然mtab就不适合/etc内单纯为不可变文件的原则,这在今后会逐步得到解决。
(未完......待续.....)