[TOC]
# 系統體系結構
我們從Linux系統體系結構開始著手了解它。

# 系統目錄結構 & 目錄結構的來歷
## 系統目錄結構
Linux 目錄結構是一個倒掛樹結構,一切從“根”節點開始“生根發芽”。

每個目錄存放的內容如下:
* /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,下文統稱“虛擬文件系統”),它不是磁盤文件的組織格式,而是抽象出來的文件樹的集合,它通過標準接口動態的向其中增加或移除對應的目錄。

虛擬文件系統支持以下歸類的三種類型的文件系統:
* 磁盤文件系統,存儲在本地磁盤、U盤、CDROM等的文件系統,它包含各種不同的文件系統格式,比如Windows NTFS、VFAT,BSD的UFS,CD的CD-ROM等
* 網絡文件系統,它們存儲在網絡中的其他主機上,通過網絡進行訪問,例如 NFS
* 特殊文件系統,內存的映射、例如/proc
案例如以下截圖,Linux上的進程通過Sytem Calls(系統調用)將數據經過虛擬文件系統最終的轉寫入不同的文件系統格式,再通過文件系統的驅動最終寫入硬件設備。這里的Sytem Calls就包含read()、write()和lseek()等。

## 虛擬文件系統對象類型
虛擬文件系統,有四個主要對象類型:
* 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。