[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。