0
点赞
收藏
分享

微信扫一扫

Linux目录结构和根文件系统全面讲解

回顾:

如何使用帮助:
help
--help,man,info
自带文档(README,CHANGELOG,INSTALL)官方文档
发行版的文档
Google

Linux Kerenl: Documention

manual:使用手册

whatis keyword
man # KEYWORD 查看指定章节下的对应的关键词的使用手册

SECTION:
NAME
SYNOPSIS
[],<>,|,{}
...

控制命令:
Space,b

基础命令: pwd,cd,ls,echo,date,clock,cal,hwclock,cat,tac,file,type,tty,halt, poweroff,shutdown,reboot

Linux组成部分:
硬件,内核,系统调用,壳shell\库函数,应用

我们说过Linux的整个系统包括硬件的组成部分,由内而外。能够直接操作硬件的只能
是内核,因此内核把整个硬件给封装了起来。所有硬件所提供的硬件规格被隐藏起来并且
内核通过System call,向外提供。把所有硬件所提供的功能转换成了系统
调用。所有我们说过任何程序要想能够和内核打交道,大多数情况得通过系统调用来实现。

为什么呢?我们能不能用不允许的姿势去打开内核?当然不允许。如果允许的话内核很
容易就可以被一个程序搞崩溃。因此我们说过内核经过精心设计以后,把底层硬件的
规格细节给隐藏起来并抽象为系统调用。外部的任何程序员要想能够通过操作系统给
硬件打交道话。那么他只能通过系统调用来实现。但是我们有说内核不负责任何具体
的工作,它通常只做一些通用性的任务。

比如:进程管理,把一个静态的程序运行起来成为动态的有生命周期的进程,我们要
靠内核来管理。内存管理、文件系统、硬件驱动、网络功能、安全加密等等等。
就有很多通用的功能要在内核中实现,但是在次强调内核不负责任何具体的工作,
所有的具体工都要靠应用程序来完成。

一个程序员在开发程序时,它可以直接通过系统调用来开发。我们说过也可通过库函数
来实现。但是我们说过库这个东西仅仅为了简化程序员研发的困难度的。所以有了库以
后我们可以把很多功能提供成为公共功能模块。所以把它称为库。一旦库编译完成了
它们也是二进制可执行文件,但是库文件是没有单独的、独立的入口的只能通过被其
他程序调用时方可运行。

各种应用程序,如果这个应用程序在研发时程序员调用了库,这个程序执行启动为进程
时首先得把依赖到的库装载到内存中才能运行的。因为库本身就是这个程序的组成部分
如果一个程序员在开发时,他也调用了库,但是在编译时做了静态编译。

所谓静态编译指的是:这个程序员在程序提供编译好以后,他也调用了库。但是我们
在编译的时候把所调用的每一个库都直接编译进程序了。就意味着说把每一个依赖的库
复制了一份副本直接放在程序中,程序到任何位置都可以运行了,就不再用调用了。

Linux文件系统:

Linux:glibc

程序的编译方式:
动态链接
静态链接

这个程序编译方式指的是即编译时是否把对应所依赖到的库直接复制一份副本并编译
进自己程序内部。把他分为两种,第一种叫动态链接式编译,另一种叫做静态链接式
编译。它们之间的区别在于库文件事先是存储在操作系统之上。对Linux而言
由glibc提供。对我们Linux操作系统来讲我们通用的公共的系统库由glibc提供。
就是GNU的标准C库,这些是我们操作系统上是必须提供的一个最基本的库。
而且市面上我们所能见到的绝大多数应用程序它们都几乎或多或少的调用了库当中
的某些函数。

因此对于我们整个系统来讲,如果说一个程序在编译时它做了所谓的静态编译和动态
编译有什么区别?库当中有功能模块,它们都是程序片段是程序员所开发的。
但这些程序不能独立运行,只能够在被调用时方可运行。而且这些库文件可能会
被打包成多个包,组合起来构成多个组成部分。或者是很有可能把多个库文件组合
在一起通过一个文件来提供。

编译是什么:把程序的源代码转换成二进制格式的CPU指令,或者转换成汇编
代码的过程。
我们将来编译时就有了两种方式,第一种方式是我编译程序时,任何一个程序员
所开发的程序指的是C程序有可能都调用了某个库文件。就意味这个下次这个程序
想能运行。他的运行过程当中需要运行这个库文件。问题是我把程序编译出来以后
怎么去把用到的库文件代码能够让这个程序调用呢?也就有了两种方式。

第一种方式,我们把程序独立编译完。并且在编译的时候明确说明我将来如果调用库
的话,到哪里去调用,明确指明了库的调用入口。所以就意味着将来这个程序要想运行
,每一次想运行的话,我们把程序装载到内核上并且内核随之把库文件装载进来。
否则程序将不能运行。这种编译称为动态编译。在需要时去调用。

如果说我把编译好的程序拿到另外一个系统上去呢?另一个系统没有这两个库文件。
还能不能运行,是不能运行的。所以我们想要让另一个系统上也能运行必须要把所
需要的库文件复制过去。并且需要在相应路径下提供。

另外一个,如果我们将来不希望一个程序移动到其他系统上是有那么强的依赖性。
我们还可以给他做所谓静态编译的方式,什么叫静态编译呢?每在一个程序编译时
直接把程序所需要的库文件复制到程序内部。好处在于程序的移植性变高了。
缺点是程序体积变大。它们之所以叫共享库并不是因为在静态角度是共享的还因为
在动态角度依然是共享的。意思是一旦我们需要运行时,我们把库载入内存之后,
多个程序都调用的话没事,只需要存一份就够了因此动态链接的方式能够大大节约
内存空间。

应用程序在编写时,可以通过直接调用系统调用来实现也可以调用库函数来实现。
也可以调用库函数。库函数进一步封装了了系统调用,使得它的调用机制和调用接口
更简单,更简化而且更接近程序员。但是任何程序要想运行,那通常无非有两种方式
一种是操作系统启动以后能自动运行,这个叫开机自动运行
还有一种操作系统启动以后,用户登录系统,由用户交互式启动。
用户交互式启动要通过什么?通过终端完成。

终端:硬件设备,关联一个用户接口

进程的类型:
与终端相关:通过终端启动
与终端无关:操作系统引导启动过程当中自动启动


进程启动也有两种模式,根据启动程序的时候是否是通过终端运行。
他就有了两种类型。第一种叫做与终端相关,通过终端启动。
另一种与终端无关,操作系统引导启动过程当中自动启动。

一个操作系统的组成部分就是由一个内核文件和各种各样的程序文件,
库文件组成。而如果从广义的角度来讲我们认为库文件也是程序文件。

操作系统的组成:
静态:kernel,application

文件系统:层级结构

这个文件系统是如何和硬盘建立起关联关系的?
我们的硬盘一般是可以分区的,对Windows分了C、D、E盘各种分区。
分区指的是什么呢?为什么要做分区呢?简单来讲,一块磁盘给你了没有对磁盘
空间进行分类。分区就是把一个大空间切割成多个小空间,没一块空间都可以自治
对Linux而言所有的文件都必须从根开始。如果磁盘有多个空间如何与根建立关系?
挂载
文件系统的关联过程

我们在操作系统安装时,我们选择如何分区,由我们自己选择那个分区成为根分区。

内核文件也不过是根下的一个文件而已这是静态的视角。

动态的视角呢?
我们都知道,操作系统一开机要启动起来。所谓启动意味着什么呢?简单来描述,
第一系统启动的时候先找到内核,内核要获取要控制所有硬件。但是内核
被启动之前是谁在控制硬件呢?是主板上的BIOS程序控制。这些程序要加载到
硬盘上某一段程序来控制。随后第一个加载的所谓用户可管理的程序就是内核程序
。所以这样子我们在内存当中,首先就是内核运行,内核启动完成后下一步。

在操作系统刚启动的时候文件树是没有被激活的,是主板上的某些程序,
通过另外一套机制能找到磁盘上的内核文件。把内核文件启动在内存当中,
接着内核一旦自己启动起来以后,就掌握了整个硬件控制权。
内核会找到磁盘上的根分区,接下来启动各种应用程序,
把它激活并装载到内存之中。当然装载的时候不需要把整个分区装载进去,
而是只需要装载那个根位置。以及根之下最必要的一些路径装载到内存中。

FHS:
Filesystem Hierarchy Standard 文件系统层级结构标准

这个定义的标准描述了根之下应该具有哪些目录,它们分别有什么作用都做了
详细的描述。这些目录结构对所有发行版来讲,都应该遵循这套规范。
所以我们要学习Linux文件系统,或者我们将来想在Linux的系统使用
上做到游刃有余,必须要了解每个目录的作用。

Linux文件系统目录功能

/bin:  所有用户可使用的基本命令程序文件
/sbin: 提供系统管理使用的工具程序
/boot: 引导加载器必须用到的各静态文件:kernel,initramfs(inited),grub
/dev: 存储特殊文件或设备文件

设备有两种类型:字符设备(线性设备)
块设备(随机设备)

字符设备指的是数据交换是以字符为单位进行的。
块设备指的是什么呢?可以把多个字符打包成一个单位,来进行发送。

我们显示器也是字符设备,键盘也是。

刷新频率指的是什么呢?每秒钟把整个屏幕激发一遍的次数。

块设备:硬盘是最典型的块设备, 因为硬盘上的数据我们在实现访问时
并不按照字节访问的。怎么访问呢?我们把硬盘上的文件,
或者存储空间事先划分成固定大小的块。比如通常是1K、2K或4K的块。
我们实现存取时一次取走这样一个块。按最小单位来进行存取。

块设备和字符设备还有一个特点,它们各自有另外一个称呼字符设备叫线性设备。
线状就是有时序的。块设备也就随机设备。它的特点是。
我们可以任意访问任意数据。

/etc: 系统程序的配置文件,只能为静态

而/etc也是一个独立的层级结构, 在这个层级下必须有4个目录
opt:专门为这个目录下文件提供配置文件
X11:专门为你的图形界面程序提供配置的
sgml:专门为sgml这个格式的配置文件提供保存路径的
xml:

《奇点临近》书籍推荐

/home: 普通用户的家目录的集中位置。一般每个普通用户的家目录默认为此目录下
与用户名同名的子目录,/home/USERNAME

/root: 管理员的家目录,可选。 不要使用管理员登录

/lib: 为系统启动或根文件系统上的应用程序(/bin,/sbin等)提供共享库,以及
为内核提供内核模块。

libc.so.*: 动态链接的C库
ld*: 运行时连接器/加载器
modules: 用于存储内核模块的目录

/lib64: 64位系统特有的存放64位共享库的路径。

lib64用来做什么的?这是另外一个基本共享库,但它是可选择的。
对32系统是可选的,对64位系统是必要的。这两个都是存放库文件的。

对lib而言这主要是为/bin和/sbin下的应用程序提供共享库的。哪些放在
/user/bin和/user/sbin共享库放在/user/lib。
不过 /user/bin和/user/sbin下的哪些程序文件也有可能依赖于lib和lib64。

/media: 便携式设备挂载点。cdrom,floppy

media和mnt它们之间有什么联系和区别呢?
任何其他设备。比如我们现在除了这个硬盘的分区之外,我又插了一个U盘上来
这个U盘设备。我们怎么去访问它呢?U盘一旦插到系统以后,
我们说过对Linux而言普遍,要和根目录建立联系的。不然无法使用。
我们必须找一个空路径,没有使用的路径,然后把U盘的存储空间关联到这个路径
上来。这个就叫做挂载的过程。空目录就称为挂载点。

问题是我们任何一个设备都应该挂载到那个目录下呢?
比如拿了一个光盘过来,这个光盘应该挂载到哪里呢?
任何一个没人用的空目录都可以。非关键性目录都可以。
但是为了避免混乱,我们定了两个路径专门用来挂载这些移动设备。或者是硬盘。

/mnt: 其他文件系统的临时挂载点

/opt: 附加应用程序的安装位置,可选路径

/srv: 当前主机为服务提供的数据。

/tmp: 为那些会产生临时文件的程序,提供的用于存储临时文件的目录,可供所用户
执行写入操作。有特殊权限。

/usr: usr Hierarchy
全局共享的只读数据路径
bin,sbin,lib,lib64,
include:C程序头文件
share:命令手册页和命令自带文档等架构特有的文件的存储位置
local: 另一个层级目录
X11R6: X-Window程序的安装位置
src:程序源码文件的存储位置

usr是用来做什么的呢?除了根以外它是最重要的。

/usr/local: Local Hierarchy
让系统管理员安装本地应用程序,也通常用于安装第三方程序。

/var: /var Hierarchy
存储经常发生变化的数据的目录,如日志等

/proc:基于内存的虚拟文件系统,用于内核及进程存储其相关信息,而且将这些信息 的存储形式抽象为文件系统格式。它们多为内核参数。

例如:net.ipv4.ip_forward,虚拟为net/ipv4/ip_forward这个路径。
存储于/proc/sys/,因此其完整路径为/proc/sys/net/ipv4/ip_forward


内核的信息向外输出是通过内核参数来实现的,但是如果我们要查看内核参数
的话又只能使用另外一套机制。这与我们的一切皆文件的思想不相符。
所以为了避免这个问题该怎么办?它们把内核的参数虚拟为目录、文件。

/sys: sysfs虚拟文件系统提供了一种比proc更为理想的访问内核数据的途径。
其主要作用在于为管理Linux设备提供了一种统一模型的接口。

参考:https://www.ibm.com/developerworks/cn/linux/l-cn-sysfs/


总结:
Linux无非就是启动以后在内核中有个文件系统,而这个文件系统事实上
是挂载到内核上的。内核可以通过这个文件系统来访问任何一个文件。
必要的时候把一个程序启动起来,让程序访问它自己的配置文件。
而组织在磁盘上的时候即便内核也不例外。它其实就是某个磁盘分区下的文件。
但是我们分区很多时,分区不能够随意的各自分开被访问,
它们需要一个头叫做根,在根之下找一个未使用的目录去关联起来,
从而多个存储设备组织成统一的入口的文件系统,我们称为根文件系统,
但是这些设备在关联前,都是独立的有自己必备的文件系统。

Linux系统上的文件类型:

这个文件类型指的是基于文件系统的视角来查看这个文件到底属于那种类型,
而不是文件内容的类型。我们此前曾经使用file命令可以查看一个文件内部的
内容组织结构比如可以是一个文本文件,或者是一个二进制格式文件等等。
但是从文件系统组织文件的角度来讲它也有很多类型。

-: 常规文件。即f;
d: directory,目录文件;是实现路径映射的,不像Windows的文件夹。
b: block device,块设备文件,支持以“block”为单位进行随机访问
c: character device,字符设备文件,支持以“character”为单位进行线性访问
major number:主设备号,用标识设备类型,进而确定要加载的驱动程序
minor number:次设备号,用于标识同一类型中的不同的设备
8位二进制:0-255
l: symbolic link,符号链接文件,相当于Windows的快捷方式。

比如在D盘或者E盘上点击右键可以发送到桌面快捷方式。那个快捷方式本身不是
一个文件,也不是一个完整的文件,但它却是指向另外一个文件的路径。
是能够让你找到另外一个文件的路径,像这种我们称为符号链接文件,
也叫软连接文件

p: pipe,命名管道;管道文件
s: socket,套接字文件;两个进程进行通信时进行套接的; 用于服务的提供;

举报

相关推荐

0 条评论