我们在前面学习的过程中有了解到,linux的发现版有很多种类型,那么如果每个版本都有着自己的想法去配置文件应该放置的目录,那么将造成管理上的困扰,于是为了解决这个问题,就有了FHS标准。
1.1.1 软件的概念
之前,我们提到过,一个完整的计算机系统应该有两部分组成,即:计算机系统=软件+硬件。没有软件的硬件,计算机只不过是一堆只会发热的废铁。我们之前也比喻了,如果将硬件比喻成躯体,那么软件就是它的灵魂。软件有应用软件和系统软件之分,而操作系统就是一款系统软件。对于一个完整的操作系统来说,我们可以将它理解为:内核+程序。
我们要知道的是,要想要计算机进行相关的工作,那么必须要让CPU接受到相关的指令,这样CPU才能进行相关的操作。但是,对于我们人来说,理解这个CPU指令实在太难了。在早期,程序员通过汇编语言写程序,然后由汇编器转换成机器可以认识的机器语言。使用汇编语言的缺点是:代码冗长并且难以编写,另外还不具有兼容性。后来C语言出现了,至少我们现在要明白的是,用C语言编写的程序和硬件没啥多大关系,并且Linux内核大部分都是用C语言来编写的。
C源代码被组织成了多个子程序,每个子程序单独执行某一个任务,我们可以把它称为模块,那么Linux内核就是由许多单独的C源代码模块组成。每个模块都有其自身的子程序和数据结构,这些模块组合起来又能共同完成某种更为复杂的功能,如文件处理。
不管是汇编程序也好,C语言程序也好,它们都要转换成机器所认识的机器指令,对于C语言程序来说,处理一般经过四个处理阶段:预处理阶段、编译阶段、汇编阶段和链接阶段。如下图:
在预处理阶段中,gcc会把C程序传递给C前处理器CPP,对C语言程序中指示符和宏进行替换处理,输出纯C语言代码。这是什么意思呢?那么学习C语言的都知道,我们在写程序的时候,应该有这样写过:
#include<stdio.> #define PI 3.1415926 int main(void){ printf("hello\n"); return 0; }
那么,在预处理的时候,前处理器CPP就会将以#开头的指示符,如#include<stdio.h>、#define PI 3.1415926进行预处理。前面代表的是标准输出,后面代表的是将3.1415926替换成PI。
编译阶段,将C语言程序编译成汇编代码。
汇编阶段,将汇编代码编译成机器指令,并以特定的二进制格式保存在目标文件中。
链接阶段,最后,通过ld链接器把程序相关的目标文件和库文件组合链接在一起,这样就生成了可执行文件。
那么对于链接这个过程,我们现在知道,它是将目标文件和一些库文件连接起来形成一个单一的程序。那么,这种链接方式我们称为静态链接。但是要知道的是静态链接的最大缺点是生成的可执行文件太大,需要更多的系统资源,在装入内存时也会消耗更多的时间。随着静态链接方式诸多缺点逐一暴露出来,比如浪费内存和磁盘空间,模块更新困难。那么我们就需要一种更好的方式来组织程序。
为了解决内存和磁盘空间上的浪费和模块更新困难,我们不再通过静态链接的方式将各个模块链接到一起,简单的说,不对那些组成程序的库文件进行绑定了,而是将这些库文件根据其功能划分开来,形成一个独立的文件,但是它们不能运行,只能被调用。
如果你还是不明白,我们换种方式来描述一下:
我们说过,所谓的链接,就是将目标文件和一些功能模块组合起来形成一个能够完成单一任务的程序。那么,根据这些模块的功能描述,我们将这些相似功能的模块打包在一个单元中,这些单元能够被程序开发人员所共享,我们把这些共享单元集合在一起叫做库。Linux支持两种类型的库,即动态库和静态库,所谓的静态库就是说,在程序编译时,将该库中的某个模块绑定到程序中去。动态库则不同,它是在应用程序时被加载到内核而被加载的,而且它与应用程序是在运行时绑定的。也就是说,当我们开发人员在开发程序的时候,编译时并没有把相关的模块与应用程序绑定,而只是提供了一个调用接口(API接口),当程序运行时,内核将程序加载至虚拟地址空间,并且内核需将这个程序的相关模块装载进来之后,这个程序才能执行。
在Linux中,这些库文件主要存放在C库中,即我们叫做glibc。
那么,说了这么多,这里我们也应该理解了,对于Linux内核来说,如果没有应用程序,那么仅仅靠一个内核是没有用的。那么对于一个应用程序的运行,它主要通过两种方式来启动。一种是通过终端启动,另一种是在操作引导启动过程当中自动启动。那么不管是哪种启动方式,它最终要被加载至内核的虚拟地址空间。
1.1.2 文件系统的概念
在Linux系统当中,应用程序是以文件的形式存在,问题就是,Linux上有许多应用程序,那么是如何有效管理这众多文件的呢?那么这里就要说一下文件系统了。文件系统是操作系统中最基层的组织,操作系统与用户进行交互的方式取决于文件系统是怎样在磁盘上有效的组织文件。文件系统提供了一个公共文件系统结构,确保用户能够访问和写文件。
文件系统将文件大致分区两个逻辑类别:
Shareable vs. unsharable files
Variable vs. static files
Shareable文件可以被本地主机和远程主机访问,unsharable文件只能被本地主机访问,variable文件表示可以动态的文件,如文档,可以随时被修改,static文件表示不能被修改(除管理员操作之外),如一些二进制文件。
文件以这样的形式分类有助于将每个文件的功能与权限分配给持有这个文件相关的目录,用户要访问一个文件的前提是,这个文件是放置在哪个目录中?这个目录是否挂载并且用户是否拥有其相关的权限,已经用户是否有对这个文件的访问权限,那么可见,这种分级是至关重要的,这样保证了文件系统的安全。FHS就定义了类似这样,它定义了文件的类型,文件应该存放的目录,已经用户对目录的访问权限等定义。
那么什么是目录呢?目录就是文件的路径映射,在Linux中,文件系统不是通过设备标志符来访问,而是通过表示文件系统的层次树结构来进行访问。我们可以使用tree命令来查看一下CentOS的目录结构。
[root@MyLabC7 ~]# tree -L 1 / / |-- bin -> usr/bin |-- boot |-- dev |-- etc |-- home |-- lib -> usr/lib |-- lib64 -> usr/lib64 |-- media |-- mnt |-- opt |-- proc |-- root |-- run |-- sbin -> usr/sbin |-- srv |-- sys |-- tmp |-- usr `-- var
这里我们列出来的只是/下的目录,有必要说明一下的是,Linux层次结构遵循着FHS标准。对于FHS标准,它针对以下三个目录来进行定义,分别是 / 、/usr、/var。其它的用户可以选择性的去定义、选择。我们针对这三层目录来进行说明。
The Root Filesystem
/目录是是所有目录的起点,所有的目录都挂载在 / 目录下,当系统开机的时候,内核会从磁盘中加载/,我们也可以换句话说,/ 目录与系统开机有关。FHS标准建议/目录所在分区应该越小越好,且应用程序所安装的软件最好不要和/目录放在同一分区内,保持/目录越小越好。如此不但效能较佳,/目录所在的文件系统也不容易发生问题。
那么在/目录中,会放入哪些文件了,这里是由FHS标准已经定义好的,并且FHS标准也不建议我们在/分区中去创建目录。
现在,我们来说说,放在/目录下的这些目录到底是用来干嘛的。
Ø /bin:Essential user command binaries (for use by all users)
二进制程序文件的存放目录,在CentOS7中,这个目录为链接文件,指向/usr/bin。
Ø /boot: Static files of the boot loader
该目录包含了系统开机时需要的静态文件,如:内核常用文件名:vmlinuz。grub2这个开机管理程序还会有/boot/grub2这个目录。
Ø /dev: Device files
在linux中,一切皆文件,当然也将设备虚拟成了文件。这些设备在/dev下以两种形式存在。一种是字符设备(串行的数据流,如鼠标,键盘),另一种是块设备(随机访问,如硬盘)
Ø /etc : Host-specific system configuration
系统程序配置文件存放的目录,该目录里面的文件都是静态文件。
Ø /home : User home directories
普通的家目录的集中位置;一般每个普通用户的家目录默认为此目录下与用户名同名的子目录,/home/USERNAME;
Ø /lib : Essential shared libraries and kernel modules
为系统启动或根文件系统上的应用程序(/bin, /sbin等)提供共享库,以及为内核提供内核模块,在CentOS7上,这个目录为链接文件 ,指向/usr/lib。
如果你的机器是64位,那么与之对应的库目录就是:/lib64,这也是个链接文件,执行/usr/lib64。
Ø /media : Mount point for removeable media
便携式设备挂载点,cdrom, floppy等;
Ø /mnt : Mount point for a temporarily mounted filesystem
其它文件系统的临时挂载点;
Ø /opt : Add-on application software packages
附加应用程序的安装位置;可选路径;
Ø /root : Home directory for the root user
管理员用户的家目录。
Ø /sbin : System binaries
管理员能够执行的二进制程序的指令存放目录,在CentOS7中,是/usr/sbin的链接目录。
Ø /srv : Data for services provided by this system
srv可以视为service的缩写,表示当前主机为服务提供的数据;
Ø /tmp : Temporary files
为那些会产生临时文件的程序提供的用于存储临时文件的目录;可供所用户执行写入操作;有特殊权限;
Ø /proc : Kernel and process information virtual filesystem
它是一个虚拟的文件系统,在内存里存放,所以不占磁盘空间,用于为内核及进程存储其相关信息,而且将这些系统信息抽象为了文件系统格式;它们多为内核参数,例如net.ipv4.ip_forward, 虚拟为net/ipv4/ip_forward, 存储于/proc/sys/, 因此其完整路径为/proc/sys/net/ipv4/ip_forward;
Ø /sys
sysfs虚拟文件系统提供了一种比proc更为理想的访问内核数据的途径;其主要作用在于为管理Linux设备提供一种统一模型的的接口;
sysfs 是 Linux 内核中设计较新的一种虚拟的基于内存的文件系统,它的作用与 proc 有些类似,但除了与 proc 相同的具有查看和设定内核参数功能之外,还有为 Linux 统一设备模型作为管理之用。相比于 proc 文件系统,使用 sysfs 导出内核数据的方式更为统一,并且组织的方式更好,它的设计从 proc 中吸取了很多教训。
sysfs 文件系统总是被挂载在 /sys 挂载点上。
[root@MyLabC7 ~]# ls /sys block bus class dev devices firmware fs hypervisor kernel module power
参考:https://www.ibm.com/developerworks/cn/linux/l-cn-sysfs/
The /usr Hierarchy
/usr目录是文件系统中第二个重要的目录,它里面中存放的是shareable、read-only的数据,这就意味着/usr目录中的文件是静态的,可共享的,并且能在兼容FHS的主机上使用。一般建议单独分区。现在我们来看一下,/usr下应该包含哪些子目录。
[root@MyLabC7 ~]# tree -L 1 /usr /usr ├── bin ├── etc ├── games ├── include ├── lib ├── lib64 ├── libexec ├── local ├── sbin ├── share ├── src └── tmp -> ../var/tmp
同样的,我们来说说,一些重要的目录是用来干嘛的:
Ø /usr/bin: Essential user command binaries
用户二进制存放的路径
Ø /usr/include : Directory for standard include files
C或C++的函数头文件存放的目录
Ø /usr/lib : Libraries for programming and packages
为系统启动或根文件系统上的应用程序(/bin, /sbin等)提供共享库,以及为内核提供内核模块。
如果你的机器是64位,那么与之对应的库目录就是:/usr/lib64
Ø /usr/share : Architecture-independent data
命令手册页和自带文档等架构特有的文件的存储位置,如/usr/share/man
Ø /usr/sbin : System binaries
管理员能够执行的二进制程序的指令存放目录
Ø /usr/src : Source code
系统源代码所存放的目录
Ø /usr/local : Local hierarchy
这是管理员在本地安装软件时的层级目录,我们可以使用tree查看一下:
[root@MyLabC7 ~]# tree -L 1 /usr/local /usr/local ├── bin ├── etc ├── games ├── include ├── lib ├── lib64 ├── libexec ├── sbin ├── share └── src
这里我们根据我们上面的目录结构的理解,这些我们应该能明白是什么意思。
The /var Hierarchy
如果说/usr是安装时会占用磁盘较大容量的目录,那么/var就是系统在运行后逐渐占用磁盘容量。因为/var目录主要针对一些动态文件的存放。
同样的,我们使用tree来查看一下/var下的目录结构。
[root@MyLabC7 ~]# tree -L 1 /var /var ├── account ├── adm ├── cache ├── crash ├── db ├── empty ├── games ├── gopher ├── kerberos ├── lib ├── local ├── lock -> ../run/lock ├── log ├── mail -> spool/mail ├── nis ├── opt ├── preserve ├── run -> ../run ├── spool ├── target ├── tmp └── yp
我们来说说一般常用的目录:
Ø /var/cache : Application cache data
用于缓存应用程序的数据
Ø /var/lib : Variable state information
注意,这里的lib指的不是库文件,而是系统的状态信息
Ø /var/lock : Lock files
某些设备或者文件资源一次只能被一个应用程序所使用,如果同时有两个程序使用该资源时,可能就会产生一些错误的状况,因此就得要将该设备或文件资源上锁(lock),以确保该设备或文件资源只会给单一软件所使用。 目前此目录已挪到/run/lock中
Ø /var/log : Log files and directories
系统日志文件所存放的目录
Ø /var/mail : User mailbox files
放置个人邮件信箱的目录,不过被挪到/var/spool/mail
Ø /var/opt : Variable data for /opt
安装在opt目录中的第三方应用程序所产生的可变的数据。
Ø /var/run : Run-time variable data
某些程序或服务启动时,会将它们的PID放置在这个目录下,这个目录已经挪到/run
Ø /var/spool : Application spool data
通常这个目录放置一些队列数据。所谓的队列就是排队等待其他程序使用的数据。这些数据被使用后通常都会被删除。如:系统收到新信会放置到/var/spool/mail/中,但使用者收下该信后原则上该信就会被删除。信件如果暂时寄不出去会被放到/var/spool/mqueue/中,等到被送出后就删除。如果是crontab数据,就会被放置到/var/spool/cron目录中。
原创文章,作者:N24_小辉,如若转载,请注明出处:http://www.178linux.com/54921
评论列表(1条)
详实有料,生动有趣,作者有心了,以后拿出来就可以直接当参考文档,加油!