# Linux (二) - 檔案系統架構

不同於 Windows 將文件依照硬碟存放在 C 槽、 D 槽等等,Linux 將整個文件系統視為一棵樹,樹根稱為根目錄 ( / ),文件會從根目錄開始以樹狀結構排序,如上圖。而硬碟則是透過掛載 (Mount) 的方式來接上檔案系統再進行存取。
根目錄下的目錄有很多,本文僅介紹常用的目錄。
<!-- more -->
## 基本檔案目錄操作
在開始介紹每個目錄的意義之前,我們要先簡單的了解如何操作這些目錄和檔案。
### ls
列出文件可以使用 `ls` 這個指令。
```bash=
ls [option] [file]
```
option :
* `-l` : 列出檔案詳細資訊
* `-a` : 顯示隱藏檔案
* `-F` : 顯示檔案類型
* `-r` : 以反向排序列出檔案
* `-R` : 列出目錄下所有檔案,包含目錄下的資料夾內的所有檔案
* `-t` : 依照檔案建立時間列出
* `-S` : 依照檔案大小排序
file 如果沒有指定就是當前的目錄。
#### 範例
**指定目錄**
這個範例指定列出根目錄下的檔案,根目錄的名稱就是 `/`。
```bash=
$ ls /
anaconda-post.log dev home lib64 mnt proc run srv tmp var
bin etc lib media opt root sbin sys usr
```
**列出檔案詳細資訊**
列出檔案的詳細資訊會顯示七個欄位,由左到右分別為檔案屬性、檔案數、擁有者、擁有者群組、大小、建檔時間、檔名。
檔案屬性會在下一篇作詳細介紹。
擁有者群組的意思是每個使用者會附屬在一個或多個群組下。
```bash=
$ ls -l
total 56
-rw-r--r-- 1 root root 12148 Aug 9 21:39 anaconda-post.log
lrwxrwxrwx 1 root root 7 Aug 9 21:38 bin -> usr/bin
drwxr-xr-x 5 root root 360 Sep 24 06:05 dev
drwxr-xr-x 1 root root 4096 Sep 24 06:05 etc
drwxr-xr-x 2 root root 4096 Apr 11 2018 home
lrwxrwxrwx 1 root root 7 Aug 9 21:38 lib -> usr/lib
lrwxrwxrwx 1 root root 9 Aug 9 21:38 lib64 -> usr/lib64
drwxr-xr-x 2 root root 4096 Apr 11 2018 media
drwxr-xr-x 2 root root 4096 Apr 11 2018 mnt
drwxr-xr-x 2 root root 4096 Apr 11 2018 opt
dr-xr-xr-x 132 root root 0 Sep 24 06:05 proc
dr-xr-x--- 2 root root 4096 Aug 9 21:39 root
drwxr-xr-x 11 root root 4096 Aug 9 21:39 run
lrwxrwxrwx 1 root root 8 Aug 9 21:38 sbin -> usr/sbin
drwxr-xr-x 2 root root 4096 Apr 11 2018 srv
dr-xr-xr-x 12 root root 0 Sep 24 06:38 sys
drwxrwxrwt 7 root root 4096 Aug 9 21:39 tmp
drwxr-xr-x 13 root root 4096 Aug 9 21:38 usr
drwxr-xr-x 18 root root 4096 Aug 9 21:38 var
```
**顯示隱藏檔案**
```bash=
$ ls -a
. .dockerenv bin etc lib media opt root sbin sys usr
.. anaconda-post.log dev home lib64 mnt proc run srv tmp var
```
**顯示檔案類型**
```bash=
$ ls -F
anaconda-post.log dev/ home/ lib64@ mnt/ proc/ run/ srv/ tmp/ var/
bin@ etc/ lib@ media/ opt/ root/ sbin@ sys/ usr/
```
`-F` 會依照檔案類型標記,標記的符號有以下幾種 :
* `@` : 連結檔 (symbolic link),就等同是 Windows 的捷徑。
* `*` : 可執行檔。
* `/` : 目錄,也就是資料夾。
其他還有幾種標記符號但是比較不常見就不在此介紹了。
**以反向排序列出檔案**
這個範例我們結合 `-l` 列出詳細資訊會看得比較清楚,可以注意到最後一行的名稱順序有反過來。另外可以再發現 `ls -lr` 的 `-l` 和 `-r` 是寫成 `-lr`,因為這些選項是可以多選的,而如果多選就可以寫在一起不用寫成 `-l -r`。
```bash=
$ ls -lr
total 56
drwxr-xr-x 18 root root 4096 Aug 9 21:38 var
drwxr-xr-x 13 root root 4096 Aug 9 21:38 usr
drwxrwxrwt 7 root root 4096 Aug 9 21:39 tmp
dr-xr-xr-x 12 root root 0 Sep 24 06:38 sys
drwxr-xr-x 2 root root 4096 Apr 11 2018 srv
lrwxrwxrwx 1 root root 8 Aug 9 21:38 sbin -> usr/sbin
drwxr-xr-x 11 root root 4096 Aug 9 21:39 run
dr-xr-x--- 2 root root 4096 Aug 9 21:39 root
dr-xr-xr-x 131 root root 0 Sep 24 06:05 proc
drwxr-xr-x 2 root root 4096 Apr 11 2018 opt
drwxr-xr-x 2 root root 4096 Apr 11 2018 mnt
drwxr-xr-x 2 root root 4096 Apr 11 2018 media
lrwxrwxrwx 1 root root 9 Aug 9 21:38 lib64 -> usr/lib64
lrwxrwxrwx 1 root root 7 Aug 9 21:38 lib -> usr/lib
drwxr-xr-x 2 root root 4096 Apr 11 2018 home
drwxr-xr-x 1 root root 4096 Sep 24 06:05 etc
drwxr-xr-x 5 root root 360 Sep 24 06:05 dev
lrwxrwxrwx 1 root root 7 Aug 9 21:38 bin -> usr/bin
-rw-r--r-- 1 root root 12148 Aug 9 21:39 anaconda-post.log
$ ls -l
total 56
-rw-r--r-- 1 root root 12148 Aug 9 21:39 anaconda-post.log
lrwxrwxrwx 1 root root 7 Aug 9 21:38 bin -> usr/bin
drwxr-xr-x 5 root root 360 Sep 24 06:05 dev
drwxr-xr-x 1 root root 4096 Sep 24 06:05 etc
drwxr-xr-x 2 root root 4096 Apr 11 2018 home
lrwxrwxrwx 1 root root 7 Aug 9 21:38 lib -> usr/lib
lrwxrwxrwx 1 root root 9 Aug 9 21:38 lib64 -> usr/lib64
drwxr-xr-x 2 root root 4096 Apr 11 2018 media
drwxr-xr-x 2 root root 4096 Apr 11 2018 mnt
drwxr-xr-x 2 root root 4096 Apr 11 2018 opt
dr-xr-xr-x 131 root root 0 Sep 24 06:05 proc
dr-xr-x--- 2 root root 4096 Aug 9 21:39 root
drwxr-xr-x 11 root root 4096 Aug 9 21:39 run
lrwxrwxrwx 1 root root 8 Aug 9 21:38 sbin -> usr/sbin
drwxr-xr-x 2 root root 4096 Apr 11 2018 srv
dr-xr-xr-x 12 root root 0 Sep 24 06:38 sys
drwxrwxrwt 7 root root 4096 Aug 9 21:39 tmp
drwxr-xr-x 13 root root 4096 Aug 9 21:38 usr
drwxr-xr-x 18 root root 4096 Aug 9 21:38 var
```
**列出目錄下所有檔案**
`ls -R` 列出目錄下所有檔案這裡就不示範了,如果在根目錄下會列出非常多的檔案,有興趣的話可以自己試試看。
**依照檔案建立時間列出**
這個範例同樣結合 `-l` 列出更詳細的資料,可以看到檔案會依照建立時間由新到舊依序列出來。而下面則是再結合 `-r`,讓列出的順序改成由舊到新列出。
```bash=
$ ls -lt
total 56
dr-xr-xr-x 12 root root 0 Sep 24 06:38 sys
drwxr-xr-x 5 root root 360 Sep 24 06:05 dev
dr-xr-xr-x 131 root root 0 Sep 24 06:05 proc
drwxr-xr-x 1 root root 4096 Sep 24 06:05 etc
-rw-r--r-- 1 root root 12148 Aug 9 21:39 anaconda-post.log
dr-xr-x--- 2 root root 4096 Aug 9 21:39 root
drwxr-xr-x 11 root root 4096 Aug 9 21:39 run
drwxrwxrwt 7 root root 4096 Aug 9 21:39 tmp
drwxr-xr-x 18 root root 4096 Aug 9 21:38 var
lrwxrwxrwx 1 root root 7 Aug 9 21:38 bin -> usr/bin
lrwxrwxrwx 1 root root 7 Aug 9 21:38 lib -> usr/lib
lrwxrwxrwx 1 root root 9 Aug 9 21:38 lib64 -> usr/lib64
lrwxrwxrwx 1 root root 8 Aug 9 21:38 sbin -> usr/sbin
drwxr-xr-x 13 root root 4096 Aug 9 21:38 usr
drwxr-xr-x 2 root root 4096 Apr 11 2018 home
drwxr-xr-x 2 root root 4096 Apr 11 2018 media
drwxr-xr-x 2 root root 4096 Apr 11 2018 mnt
drwxr-xr-x 2 root root 4096 Apr 11 2018 opt
drwxr-xr-x 2 root root 4096 Apr 11 2018 srv
$ ls -ltr
total 56
drwxr-xr-x 2 root root 4096 Apr 11 2018 srv
drwxr-xr-x 2 root root 4096 Apr 11 2018 opt
drwxr-xr-x 2 root root 4096 Apr 11 2018 mnt
drwxr-xr-x 2 root root 4096 Apr 11 2018 media
drwxr-xr-x 2 root root 4096 Apr 11 2018 home
drwxr-xr-x 13 root root 4096 Aug 9 21:38 usr
lrwxrwxrwx 1 root root 8 Aug 9 21:38 sbin -> usr/sbin
lrwxrwxrwx 1 root root 9 Aug 9 21:38 lib64 -> usr/lib64
lrwxrwxrwx 1 root root 7 Aug 9 21:38 lib -> usr/lib
lrwxrwxrwx 1 root root 7 Aug 9 21:38 bin -> usr/bin
drwxr-xr-x 18 root root 4096 Aug 9 21:38 var
drwxrwxrwt 7 root root 4096 Aug 9 21:39 tmp
drwxr-xr-x 11 root root 4096 Aug 9 21:39 run
dr-xr-x--- 2 root root 4096 Aug 9 21:39 root
-rw-r--r-- 1 root root 12148 Aug 9 21:39 anaconda-post.log
drwxr-xr-x 1 root root 4096 Sep 24 06:05 etc
dr-xr-xr-x 131 root root 0 Sep 24 06:05 proc
drwxr-xr-x 5 root root 360 Sep 24 06:05 dev
dr-xr-xr-x 12 root root 0 Sep 24 06:38 sys
```
**依照檔案大小排序**
這個範例同樣結合 `-l` 列出更詳細的資料,可以看到檔案由大到小依序列出,同樣可以結合 `-r` 來反轉輸出順序,這裡就不示範了。
```bash=
$ ls -lS
total 56
-rw-r--r-- 1 root root 12148 Aug 9 21:39 anaconda-post.log
drwxr-xr-x 1 root root 4096 Sep 24 06:05 etc
drwxr-xr-x 2 root root 4096 Apr 11 2018 home
drwxr-xr-x 2 root root 4096 Apr 11 2018 media
drwxr-xr-x 2 root root 4096 Apr 11 2018 mnt
drwxr-xr-x 2 root root 4096 Apr 11 2018 opt
dr-xr-x--- 2 root root 4096 Aug 9 21:39 root
drwxr-xr-x 11 root root 4096 Aug 9 21:39 run
drwxr-xr-x 2 root root 4096 Apr 11 2018 srv
drwxrwxrwt 7 root root 4096 Aug 9 21:39 tmp
drwxr-xr-x 13 root root 4096 Aug 9 21:38 usr
drwxr-xr-x 18 root root 4096 Aug 9 21:38 var
drwxr-xr-x 5 root root 360 Sep 24 06:05 dev
lrwxrwxrwx 1 root root 9 Aug 9 21:38 lib64 -> usr/lib64
lrwxrwxrwx 1 root root 8 Aug 9 21:38 sbin -> usr/sbin
lrwxrwxrwx 1 root root 7 Aug 9 21:38 bin -> usr/bin
lrwxrwxrwx 1 root root 7 Aug 9 21:38 lib -> usr/lib
dr-xr-xr-x 131 root root 0 Sep 24 06:05 proc
dr-xr-xr-x 12 root root 0 Sep 24 06:38 sys
```
### cd
cd (change directory) 可以用於切換目錄,這是一個最基本的指令,會很常使用到。
```bash=
cd [directory path]
```
**範例**
移動目錄到 `usr/bin` 目錄下,相當於點了 `usr` 資料夾後又再點進去了裡面的 `bin` 資料夾。
```bash=
$ cd /usr/bin
```
切換到使用者的主目錄,可以使用 `~` 來快速切換。
```bash=
$ cd ~
$ cd /home/<username>
```
返回上一層,使用 `../` 代表回上一層,可以一次返回多層,如下面第二行指令就是往回兩層。
```bash=
$ cd ../
$ cd ../../
```
### mkdir
mkdir (make directory) 可以用於建立目錄。
```bash=
mkdir [-p] <directory>
```
`-p` 是可以選擇的參數,會檢查如果目錄不存在才會建立,如果沒使用 `-p` 又建立已經存在的目錄就會報錯建立失敗。
**範例**
建立一個測試的資料夾,並且再次建立會發現建立失敗而且報錯,接著加上 `-p` 再建立一次就會發現並不會有錯而且指令執行成功。
```bash=
$ mkdir testDir
$ mkdir testDir
mkdir: cannot create directory 'testDir': File exists
$ mkdir -p testDir
```
## 根目錄下的各個目錄介紹
### /bin
bin 目錄是一個 Binary File,存放了提供所有使用者經常使用的命令,例如 `ls` 命令就存放在 bin 目錄下。可以在根目錄用 `ls bin` 查看 bin 目錄下有哪些命令可以用。
### /boot
boot 目錄存放的是啟動 Linux 時所需要使用的一些核心文件。
### /dev
dev 目錄存放的是所有的系統的外部設備文件,可以透過這些文件去存取外部的設備。例如 : 記憶體、硬碟、虛擬終端、Console 等等。Linux 承襲了 Unix 的風格,將所有的裝置都視為一個檔案。
```bash=
$ ls dev
console core fd full mqueue null ptmx pts random shm stderr stdin stdout tty urandom zero
```
### /etc
etc 目錄存放了大部分的系統和應用程式的主要設定檔。例如 : 開機啟動設定檔 (init.d)、安全性設定檔 (security)、使用者資料 (passwd)、應用程式 (python) 等等。這個目錄下的檔案可以被所有使用者瀏覽,但是只有 root 有權限進行修改。
### /home
home 目錄存放了使用者的個人檔案,每個使用者都會有一個以自己帳號命名的目錄在 home 下面,這個目錄就是每個使用者自己的主目錄,可以在自己的主目錄下存放個人的檔案。
例如,建立了一個帳號 `user1`,則 user1 這個使用者的主目錄的路徑就會是 `/home/user1`。
一般以使用者登入之後就會直接進到自己的主目錄下了,如果想要查看 home 目錄可以透過 `cd ../` 指令來退回上一層,就可以退到 home 目錄。
```bash=
user1@mycomputer:home$ ls
user0 user1 user2
```
### /lib
lib (library) 目錄存放了 Linux 在執行或編譯時會使用到的一些共用函式庫,包含許多應用程式執行也幾乎都需要從這裡獲取所需的函式庫來執行。
### /media
Linux 會將外部的連結設備 (硬碟、光碟機) 掛載到 media 目錄下,所以 media 目錄是外部設備的一個掛載點。例如 : 電腦接上一個隨身碟,Linux 會自動將這個隨身碟掛載到 /media 目錄下,所以檔案的路徑就會是 `/media/隨身碟名稱/<file>.<type>`。
直接下指令就可以看到現在電腦上有連接了哪些外部設備,如下 :
```bash=
user1@mycomputer:/$ ls /media/user1
Disk1 MyFlashDrive
```
### /mnt
mnt (mount) 目錄是透過手動將暫時性檔案掛載在此以進行存取,例如 : 掛載一個 .iso 檔並將資料從這個 .iso 檔取出來,取得需要的資料之後就可以卸載這個檔案。在 /media 目錄還沒有出現之前,/mnt 目錄的功能就和 /media 一樣,而現在多了 /media 目錄會自動掛載那 /mnt 就多用於暫時性的掛載了。
所以 `/mnt` 和 `/media` 的差別在於 `/media` 是系統自動將外部設備掛載在此,而 `/mnt` 是使用者手動將檔案暫時掛載在此。
### /opt
opt (option) 目錄是給第三方的軟體放置的目錄,也就是給那些自行額外安裝的軟體放的目錄。例如下面這個例子可以看到一些常見的應用 :
```bash=
user1@mycomputer:/$ ls opt
containerd google teamviewer
```
### /run
run 目錄是一個暫時的文件系統,用來儲存系統啟動之後的訊息。所以當系統重啟的時候,目錄下的文件會被刪除。
### /proc
proc (process) 目錄是一個虛擬的檔案系統,存放了當前系統運作的一些資訊,例如 : 系統核心、行程 (process) 資訊、網路狀態等等。而這些資料都是存在記憶體中,並不佔硬碟空間,所以是虛擬的檔案系統。
使用 `ls proc` 可以看到列出的檔案有一些比較重要的像是 `cpuinfo`、`ioports`、`net`。可以使用 `vi` 編輯器打開來看一下。
### /root
root 是系統管理員的主目錄,也就是 [上一篇](https://tienyulin.github.io/linux-basic-concept-command) 有介紹過的超級使用者。
### /sbin
sbin (super binaries) 目錄存放了只有系統管理員可以使用的指令,也包括了開機、修復和還原系統所需要的指令。例如 : fdisk (硬碟分割)、shutdown (關機)、ifconfig (查看網路狀態) 等等。
### /srv
srv (service) 目錄存放了一些網路服務啟動後所需要用到的資料,例如 : WWW、FTP。
### /tmp
tmp (temporary) 目錄可以用來存放一些暫時性的文件。
### /usr
usr (unix software resource) 目錄是用來存放 Unix 作業系統軟體資源,包含了作業系統的資訊和應用程式的文件,類似於 Windows 的 `C://Windows/{其中一部分}` + `C://ProgramFiles`。
### /var
var (variable) 目錄存放著常態性變動的檔案,例如 : cache (快取)、log、mail (尚未寄出的郵件或是接收郵件的地方) 等等。
## 重要的目錄
Linux 系統有幾個需要特別注意的目錄,如下 :
### /etc
這個目錄非常重要,前面有提到大部分的系統和應用程式的主要設定檔都放在此,如果不慎破壞了 /etc 目錄裡的資料很有可能會導致非常嚴重的後果,例如 : 無法開機、資料毀損等等。
而 `/etc/rc.d/rc.local` 和 `/etc/rc.d/rc.sysinit` 這兩個檔案是開機的執行檔,如果需要在開機時自動載入或執行的檔案可以寫在這兩個檔案裡。
### /bin、/sbin、/usr/bin、/usr/sbin
這些目錄會存放系統預設的檔案,前面有提到很多常用的指令都放在此。
### /var
這個目錄非常重要,不論是登入、系統或服務運行都會產生相應的 log 紀錄存放在此,所以如果系統有問題就可以從這裡查看 log 訊息來排除錯誤。
## 檔案系統階層圖
下面這張圖列出了 Linux 檔案系統中基本的架構和目錄下基本會有哪些檔案,透過這張圖可以更清楚的了解 Linux 的檔案系統。

## Summary
本篇介紹了 Linux 的基本檔案系統架構,先稍微了解基本的檔案系統架構對於學習 Linux 會有很大的幫助。Linux 將整個系統以檔案的概念來設計,包含像是指令、硬體等等,每一個就是一個檔案,所以了解了 Linux 的檔案系統架構會讓你更了解每一個操作是怎麼完成的。
## 參考
[1] [Linux 系统目錄](https://www.runoob.com/linux/linux-system-contents.html)
[2] [Linux目錄結構](http://linux-wiki.cn/wiki/zh-tw/Linux%E7%9B%AE%E5%BD%95%E7%BB%93%E6%9E%84)
[3] [Linux 的 ls 指令教學與常用範例整理](https://blog.gtwang.org/linux/linux-ls-command-tutorial/)
[4] [Linux 磁碟與檔案系統管理 | 鳥哥的 Linux 私房菜](http://linux.vbird.org/linux_basic/0230filesystem/0230filesystem-fc4.php)
[5] [Linux /dev目錄詳解和Linux系統各個目錄的作用](https://www.itread01.com/p/151833.html)
[6] [根目錄下各資料夾的功能詳細介紹](https://www.itread01.com/content/1545291200.html)
[7] [快速理解Linux目錄意義](https://t17.techbang.com/topics/5833-fully-understand-how-to-allocate-irrigation-linux-hard-disk-before?mode=print&page=1)
[8] [Linux 檔案屬性 | 鳥站](https://linux.vbird.org/linux_basic/redhat6.1/linux_05file.php)
[9] [The Linux Filesystem Explained](https://www.linux.com/training-tutorials/linux-filesystem-explained/)
###### tags: `Linux`