[TOC]
# 系统体系结构
我们从Linux系统体系结构开始着手了解它。
![](https://img.kancloud.cn/1c/07/1c0757d85c63bd95f3ed427bdc946dd5_733x622.png)
# 系统目录结构 & 目录结构的来历
## 系统目录结构
Linux 目录结构是一个倒挂树结构,一切从“根”节点开始“生根发芽”。
![](https://img.kancloud.cn/46/be/46bedd294ee4d20f4ce0a7093f9cc16b_973x241.png)
每个目录存放的内容如下:
* /bin 二进制可执行命令 (包括常用的Linux命令,任何用户都可以运行这个目录中的命令,无需授权)
* /dev 设备特殊文件
* /etc 系统管理和配置文件 (如Apache、Nginx和MySQL等)
* /home 用户的宿主目录,也称家目录
* /lib 函数库,又叫动态链接共享库。存放的文件类似 Windows 里的.dll (扩展名)文件
* /sbin 存放的系统管理命令
* /tmp 公用的临时文件存储点 (系统重启后会清空)
* /root 系统管理员的主目录(最高权限用户目录)
* /mnt 系统提供这个目录是让用户临时挂载其他的文件系统
* /proc 虚拟的目录,是系统内存的映射
* /var 存放比较大的数据文件,比方说各种服务的日志文件,系统日志文件
* /usr 存放用户应用程序的目录
## 目录结构的来历
我们可以看到根“ / ”目录下面的/bin目录用于存放二进制程序,但同样的二进制程序在/usr/bin和/usr/local/bin下都有那它们有什么区别呢。其实Linux整体设计借鉴了Unix系统,所以我们经常可以看到这样来描写Linux/Unix,这里再聊目录结构的由来就不得不提 Unix的设计。
1969年Ken Thompson和Dennis Ritchie在小型机PDP-7上发明了Unix,1971年他们将主机升级到了PDP-11,他们使用一种叫做RK05的储存盘,一盘的容量大约是1.5MB。没过多久,操作系统(根目录)变得越来越大,一块盘已经装不下了。于是,他们加上了第二盘RK05,并且规定第一块盘专门放系统程序,第二块盘专门放用户自己的程序,因此挂载的目录点取名为/usr。也就是说,根目录"/"挂载在第一块盘,"/usr"目录挂载在第二块盘。除此之外,两块盘的目录结构完全相同,第一块盘的目录(/bin, /sbin, /lib, /tmp...)都在/usr目录下重新出现一次。后来,第二块盘也满了,他们只好又加了第三盘RK05,挂载的目录点取名为/home,并且规定/usr用于存放用户的程序,/home用于存放用户的数据。从此,这种目录结构就延续了下来。随着硬盘容量越来越大,各个目录的含义进一步得到明确。 关于目录细节可以参考以下两篇文章:
* 《Unix文件系统结构标准》http://www.pathname.com/fhs/pub/fhs-2.3.html
* 《Understanding the bin, sbin, usr/bin , usr/sbin split》http://lists.busybox.net/pipermail/busybox/2010-December/074114.html
# 虚拟文件系统介绍
Linux使用了虚拟文件系统(VFS,Virtual FileSystem,下文统称“虚拟文件系统”),它不是磁盘文件的组织格式,而是抽象出来的文件树的集合,它通过标准接口动态的向其中增加或移除对应的目录。
![](https://img.kancloud.cn/90/34/903446b926bb2b89882160727ad26490_1214x263.png )
虚拟文件系统支持以下归类的三种类型的文件系统:
* 磁盘文件系统,存储在本地磁盘、U盘、CDROM等的文件系统,它包含各种不同的文件系统格式,比如Windows NTFS、VFAT,BSD的UFS,CD的CD-ROM等
* 网络文件系统,它们存储在网络中的其他主机上,通过网络进行访问,例如 NFS
* 特殊文件系统,内存的映射、例如/proc
案例如以下截图,Linux上的进程通过Sytem Calls(系统调用)将数据经过虚拟文件系统最终的转写入不同的文件系统格式,再通过文件系统的驱动最终写入硬件设备。这里的Sytem Calls就包含read()、write()和lseek()等。
![](https://img.kancloud.cn/cd/98/cd98e70c7ae1bef116399a5354bd4097_833x645.png =800x700)
## 虚拟文件系统对象类型
虚拟文件系统,有四个主要对象类型:
* Superblock 表示特定加载的文件系统
* Inode 表示特定的文件
* Dentry 表示一个目录项,路径的一个组成部分
* File 表示进程打开的一个文件
**Superblock**
超级块(spuerblock)对象由各自的文件系统实现,用来存储文件系统的信息。这个对象对应为文件系统超级块或者文件系统控制块,它存储在磁盘特定的扇区上。不是基于磁盘的文件系统临时生成超级块,并保存在内存中。
**Inode**
索引节点对象包含了内核在操作文件或目录时需要的全部信息。对于Unix文件系统来 说,这些信息可以从磁盘索引节点直接读入。如果一个文件系统没有索引节点,那么,不管这些相关信息在磁盘上是怎么存放的,文件系统都必须从中提取这些信息。
**Dentry**
为了方便查找,虚拟文件系统引入目录项的概念。每个Dentry代表路径中一个特定部分。对于“/bin/ls”、“/”、“bin”和“ls”都是目录项对象。前面是两个目录,最后一个是普通文件。在路径中, 包括普通文件在内,每一个部分都是目录项对象。
**File**
虚拟文件系统最后一个主要对象是文件对象,文件对象表示进程已打开的文件。如果我们站在用户空间的角度考虑虚拟文件系统,文件对象会首先进入我们的视野。进程直接处理的是文件而不是超级块、索引节点或目录。文件对象包含我们非常熟悉的信息(如访问模式、当前偏移等), 文件操作和我们非常熟悉的系统调用read()和write()等也很类似。文件对象是已打开的文件在内存中的表示。该对象(不是物理文件)由相应的open()系统调用创建,由close()系统调用销毁,所有这些文件相关的调用实际上都是文件操作 表中定义的方法。
## 文件名与路径
文件名则被指定,由文件系统的根目录开始到指定的文件位置的完整路径( /etc/sysconfig/network )称为“绝对路径”,此外表示路径的方法还有“相对路径”。在使用路径时有两种符号:
* “.” 表示当前目录
* “..” 表示上一级目录
另外 Linux 有很多不同于其他操作的特征:
1. 把所有的外部设备看作是文件(即一切揭“文件”),为了保证输入输出操作的一致性 Linux把所有的对外部设备的操作都设计成为等同于操作文件,因此无论什么外部设备的特征,都被文件系统隐藏了。
2. 文件的用有者可以指定其他的组或用户读,写和执行文件的权限,从而起到提高文件的安全性。
## 文件和目录的属性
在Linux系统中我们可以通过“ ls -l” 命令查看到文件的详细属性。
```
[djangowang@localhost ~]# ls -l
-rw-r--r-- 1 root root 1704 Aug 13 2019 GeoIP.conf # 文件
drwxr-xr-x 7 root root 4096 May 6 2020 NetworkManager # 目录
```
关于文件属性左到右第一个位的含义:
| 属性位 | 含义 |
| --- | --- |
| - | 常规文件 |
| b | 块特殊文件 |
| c | 字符特殊文件 |
| d | 目录 |
| l | 符号链接 |
| p | 管道名 |
| s | 套接字 |
再来看一下,文件属性左到右,第二到第九位的含义:
<table>
<tr>
<th></th>
<th>所属用户(user)</th>
<th>所属组(group)</th>
<th>其他用户(other)</th>
</tr >
<tr>
<td >权限</td>
<td >rwx</td>
<td >r--</td>
<td >r--</td>
</tr>
<tr>
<td >解释</td>
<td >可读(r)、可写(w)、可执行(x)</td>
<td >可执行(r) </td>
<td >可执行(r)</td>
</tr>
</table>
# 修改文件权限
修改文件权限可以使用“chmod”命令,目前有两种方式修改文件权限:
* 字母表示法
* 数字表法
**字母表示法**
以下为字母表示法的使用方式:
| 命令 | 账户属性 | 动作 | 权限 | 目标 |
| --- | --- | --- | --- | --- |
| chmod | u(user) 、g(group)、 o(other)、 all (a) | + (增加) 、 -(删除)、 =(设置)| r(读) 、w(写)、x(执行) | 文件或权限 |
我们来看一个案例给test.txt文件的user 、group和other增加可执行权限“x”。
```
[djangowang@localhost ~]# chmod a+x test.txt
[djangowang@localhost ~]# ls -l test.txt
-rwxr-xr-x 1 root root 531 1月 5 19:05 test.txt
```
删除可执行权限“x”。
```
[djangowang@localhost ~]# chmod a-x test.txt
[djangowang@localhost ~]# ls -l test.txt
-rw-r--r-- 1 root root 531 1月 5 19:05 test.txt
```
**数字表示法**
我们首先看一下数据与权限的对照表。
| 权限位 | 数字 |
| --- | --- |
| r | 4 |
| w | 2 |
| x | 1 |
| - | 0 |
所以我们要修改一个文件test.txt权限为“rwxr-x---”,可以通过以下命令。
```
[djangowang@localhost ~]# chmod 750 test.txt
```
## umask命令
umask命令可以在创建文件或目录时预设它们权限的掩码。 我们创建的文件时权限默认是644的权限,创建目录时是755的权限,主要就是这个命令导致的,但这里笔者建议非专业场景请勿改动此值。关于umask不同掩码的文件和目录权限对照表
| umask掩码值 | 文件 | 目录 |
| --- | --- | --- |
| 022 | 644 | 755 |
| 027 | 640 | 750 |
| 002 | 664 | 775 |
| 006 | 660 | 771 |
| 007 | 660 | 770 |
查看默认umask值。
```
[djangowang@localhost ~]# umask
0022
```
创建目录,系统会通过(777-027=750) 来最终赋值目录的权限。修改umask值。
```
[djangowang@localhost ~]# mkdir a && ls -l a
[djangowang@localhost ~]# umask 027 && umask
0027
[djangowang@localhost ~]# mkdir b && ls -l
drwxr-x--- 2 root root 4096 2月 7 16:33 c
```
创建文件,系统会通过(644-027=640) 来最终终赋文件的权限。
```
[djangowang@localhost ~]# touch d && ls -l
-rw-r----- 1 root root 0 2月 8 09:20 d
```
*注:umask命令只能临时修改umask值,系统重启之后umask将还原成默认值。如果要永久修改umask值,需要修改/etc/profile文件或是修改/etc/bashrc文件,例如要将默认umask值设置为027,那么可以在文件中增加一行“umask 027”。*
# 本章小结
本章最开始从Linux体系结构开始讲起,从整体上让读者对学习Linux操作系统的结果有一个大框的认识。接着我们学习了Linux目录结构,介绍了每个目录存放的内容、目录特点和目录结构的来历,笔者个人觉得学一件事情了解事物的历史背景也是非常重要的。然后我们介绍了Linux的虚拟文件系统,掌握了为什么,Linux系统在插入不同的硬件后都可以识别,并以文件的方式访问它。最后我们学习了Linux操作系统的两种修改权限方式,之所以说Linux系统相对比较安全就是因为它有严格的权限控制,权限控制就包含了系统级别如pam和文件级别的权限控制。下一章我们会介绍Linux的基础命令,Linux有1000多个系统命令,每个命令又有平均10个左右参数,想要完全记忆它们是不可能的,笔者将结合自己的工作经历,将这些命令分为两类介绍,其中第一类为常用的基础系统命令,另外一类是带场景的系统管理命令,希望能帮助读者更好的记忆它们。
# 习题
1. Linux系统中的主要目录都有哪些?它们的特点是什么?
2. 虚拟文件系统的作用是什么?
3. 创建一个key.pem文件,并授权文件权限为600。