---
title: FHS 檔案系統階層標準
---
[TOC]
<style>
.bg1 {
padding: 0 5px;
white-space: pre-line;
border-radius: 2px;
background-color: black;
color: white;
}
.bg2 {
padding: 0 5px;
white-space: pre-line;
border-radius: 2px;
background-color: black;
color: skyblue;
}
</style>
<!--
目標:讓學生了解linux的檔案目錄結構(FHS)與基礎指令
*要讓學生知道哪個檔案會在哪個目錄中 (表格練習)
ex.開機檔案在? /boot
方法:先教學生基礎bash指令->先學怎麼用(30 min?),再講解FHS->再學其結構(60 min?)(先應用再理論)
群組是為了將多個使用者集合在一起,便於管理權限和資源。每個使用者可以屬於一個或多個群組,這些群組為使用者分配相同的資源和權限。
而 Linux 的檔案系統使用三種權限來控制誰可以對檔案和目錄進行操作:
* 擁有者(Owner):檔案的創建者,一般是使用者。
* 群組(Group):與檔案相關聯的群組,群組成員可以根據設定對檔案進行操作。
* 其他人(Others):不屬於擁有者或群組的其他使用者。
-->
# FHS 上課檔案
## Linux 簡介
#### 歷史
* 早期的作業系統是要錢的(UNIX),使用時需要支付昂貴的許可費
> 歷史背景是當時都是 mainframe 而沒啥「個人電腦」,後來個人電腦(PC, Personal Computer )才出來
* The first open source in the world is Unix level 6.
* 後續出現 MINIX,由計算機科學家 Andrew S. Tanenbaum 為了**教學目的**而開發的一個簡化版的 UNIX。
* 計算機科學家 Linus Torvalds ,他受到了 MINIX 的啟發,想要開發一個可以在個人電腦上執行的 OS ,決定編寫一個新的 OS ,這就是 Linux 核心(Linux kernel)的誕生。
#### 特點
* **萬物皆檔案**:在 Linux 中,硬碟、鍵盤、滑鼠等會被表示為檔案,執行的 Process 也會被表示為檔案,甚至是我們下的一些指令也是以檔案型態存在在電腦中。
* **檔案系統的資料結構**:Linux 使用 inode(index node)來定位各種檔案在磁區的位置,像是檔案、目錄、裝置檔案、socket 等都會有數個 inode。
> 透過 inode 在磁碟空間的茫茫大海中找到檔案位置
每個 inode 除了會儲存了檔案的屬性和磁區位置外,也會包含了其他資料如:最後修改時間、檔案擁有者(owner)等權限相關資料,**但不包括檔案名稱與檔案內容本身**。
* **多使用者作業系統**,可能很少會看到有人使用 Linux 當作個人電腦的主系統,但 Linux 最強大的地方是適合多個使用者在同一系統上工作。

每個使用者都擁有各自的帳戶、檔案和設定,並且每個人都有獨立的工作環境,大家在同一系統工作時幾乎不會互相影響。
> 截至2024九月,目前桌機與筆電大部分都是 Windows,佔71.47%,位居第二則是 macOS,有 15.45%,Linux 的使用者佔 6.28%,但別忘了 Android 使用的也是 Linux 核心,如果加上 Android 那可觀的市占率,Linux 就是市佔最大的 OS ㄛ ouo
世界上前500個最快的電腦全都是用 Linux kernal
## 前情指令
| 指令|簡介|
|-|-|
|cd|<font color="red">c</font>hange <font color="red">d</font>irectory 切換路徑|
|ls|<font color="red">l</font>i<font color="red">s</font>t 將當前目錄底下的檔案列出來<br>|
|sudo|<font color="red">S</font>uper <font color="red">U</font>ser <font color="red">D</font>O sudo 通常會被加在某一個指令的前面,以電腦管理員身份執行該指令。|
|^c |Ctrl c,中斷進行中的程式|
|^z |Ctrl z,暫停但不中斷|
|^l|清除之前的畫面|
## FHS 檔案系統階層標準
* 全名:Filesystem Hierarchy Standard
* 為什麼要用 FHS?
因為用 Linux 來開發產品公司與個人太多,因此訂定一個檔案系統階層標準來規範檔案的目錄位置。
FHS 旨在定義一個**標準的檔案系統層次結構**,使各種 Linux 發行版本的檔案和目錄位置保持一致。這樣,應用程式開發員和系統管理員不必擔心每個版本有不同的檔案位置,讓 Linux 有高移植性。
> 如果妳曾經使用過 Windows 系統的話,會發現妳的檔案總管內有好多的裝置,包括 C 槽、 D 槽、光碟機、 可攜式硬碟機、USB 裝置....一大堆東西。那麼 Linux 有沒有這些東西呢?答案是....沒有這些『代號』了
Linux 已經沒有所謂的裝置名稱了,所以當然也沒有 C, D... 槽。那麼我們的檔案要如何放置?
其實 Linux (或 Unix-Like,類 Unix 系統) 使用的是**單一根目錄理念**、目錄樹。最頂層的目錄為根目錄 (/),所有的目錄都在這個根目錄之下。這樣一來無論系統中有多少磁碟或分區,它們都被掛載到一個統一的目錄結構中。這個目錄樹也是整個檔案的基礎!如果你以檔案總管的想法來思考的話,如同下圖所示:


> 在 Windows 中,每分出一個磁區就需要一個磁碟機代號(如 C:、D:),雖然直觀但不夠靈活,隨著設備的更新(如插入 USB、安裝新的硬碟),這些磁碟機代號的改變,會導致應用程式或使用者無法找到想要的檔案。
<br>
<p class="text-center" style="font-size:30px; font-weight:700;">"Linux 中萬物皆檔案 Everything is a file"</p>
## 如何理解Linux中萬物皆檔案?
1. Device:在 Linux 中,設備(如硬碟、鍵盤、滑鼠等)會被表示為檔案,透過檔案系統中的 **設備檔案** `/dev/sda`來存取和操作裝置。
2. Process:每個執行的行程都被表示為檔案,可以在`/proc`目錄下找到相應的檔案,如`/proc/{PID}/status`和`/proc/{PID}/cmdline`。
3. 網路檔案:網路連線、套接字和網路介面等也被表示為檔案。例如,套接字檔案可以在`/proc/net`目錄下找到。
4. 檔案和目錄:檔案和目錄是最常見的概念,它們被用於儲存資料、設定資訊和程式碼等。在 Linux 中,檔案和目錄也被抽象化為檔案的形式,並透過檔案系統進行管理和存取。
## Linux 檔案權限
> **多使用者作業系統**,可能很少會看到有人使用 Linux 當作個人電腦的主系統,但 Linux 最強大的地方是適合多個使用者在同一系統上工作。

每個使用者都擁有各自的帳戶、檔案和設定,並且每個人都有獨立的工作環境,大家在同一系統工作時幾乎不會互相影響。
Linux 是多人多工的系統,因此可能常常會有多人同時使用這部主機來進行工作的情況, 為了考慮每個人的隱私權以及每個人喜好的工作環境,因此有了使用者與群組的概念。
- 檔案擁有者(Owner)
當一個使用者創建一個檔案時,該使用者自動成為檔案的擁有者。擁有者通常有對該檔案的讀取、寫入和執行權限,可以修改檔案的內容或刪除檔案。
- 群組(Group)
每個檔案都會分配給一個群組,該群組內的使用者將共享這個檔案的權限。
- 其他人(Others)
其他人是系統中除了檔案的擁有者和群組成員以外的所有使用者。對於其他人,檔案的擁有者可以選擇是否授予讀取、寫入或執行權限。
###### ⮕ 就像是 GOOGLE 共編的概念
## Linux 檔案屬性
#### ls 將目前目錄底下的檔案列出來
->想看到更多詳細資訊,用`ls -l`顯示詳細資訊

|顏色|代表意義|
|-|-|
|<font color="blue">藍色檔</font>|目錄|
|<span class="bg1">白色檔</span>|一般性檔,如文字檔,設定檔,源碼檔等|
|<span class="bg2">淺藍色檔</span>|連結檔、捷徑,主要是使用ln命令建立的檔|
|<font color="green">綠色檔</font>|可執行檔,可執行檔程式|
|<font color="red">紅色檔</font>|壓縮檔或包檔|
#### 其中含義

1. `白色` **檔案類型與權限(Mode)**:第一個字元表示檔案的類型:
* -:一般檔案(regular file)
* d:目錄(directory)
* l:符號連結(symbolic link)
* b:區塊設備檔案(block device file)
* c:字元設備檔案(character device file)
2. `紅色` 隨後的 9 個字元分為 3 組,分別表示檔案擁有者、群組、其他使用者的讀取、寫入與執行權限:
* r:讀取權限(read)
* w:寫入權限(write)
* x:執行權限(execute)
3. `橘色`**連結數量(Links)**:有多少 hardlink 指到此檔案。`在下面 "ln" 補充(後面會詳細說明)`
5. `黃色`**擁有者(Owner)**: 檔案的擁有者名稱。
6. `綠色`**群組(Group)**: 檔案所屬的群組名稱。
7. `藍色`**檔案大小(Size)**: 檔案的大小,以位元組(bytes)為單位。
8. `粉色`**最後修改時間(Timestamp)**: 檔案最後修改的日期和時間。格式為月、日和時間。如果修改時間超過一年,會顯示年份而非時間。
9. `紫色`**檔案名稱(Name)**: 檔案或目錄的名稱。如果是符號連結,會顯示連結到的目標。
## `/`
- `/` :root 為根目錄,是<font color="red">整個系統最重要</font>的目錄,所有的目錄都是由根目錄衍生出來的,同時根目錄也與開機/還原/系統修復等動作有關。

***
### `/bin` Binary
* 存放基本的二進制可執行檔案,例如常用的命令(如 `ls`、`cp`複製、`mv`剪貼、`cat`印出檔案內容),而這些命令在一般使用者模式
* `/bin `目錄的可執行檔案可以被當作命令使用,是因為它們位於環境變數 PATH 指定的路徑中。
* 查看當前系統的 PATH 變數`echo $PATH`
:::success
**二進制可執行檔案** 是已經被編譯成機器碼的檔案,能夠被系統直接執行。
像 Python 的 .py 等,這些以人類可讀的文本格式書寫的程式,執行時需要編譯器(compiler)將其解釋成機器碼才能執行。
使用 file 命令可以判斷某個檔案是否為二進制可執行檔案:
```bash=
file /bin/ls
/bin/ls: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked ...
```
- 牛刀小試
執行`cat /bin/ls`會出現什麼?為什麼格式會長那樣?
::: spoiler

該命令將列印二進位檔案/bin/ls的內容,這會導致亂碼。
如果你想減少「亂碼」輸出,你可以使用十六進位轉儲器:`od -ax /bin/ls | more`
:::
### `/sbin` Super user Binaries
* 開機過程中所需要的檔案。
* 開機、修復、還原系統所需要的指令。
* 系統管理員會用到的指令,例如 ifconfig、shutdown 等。
`sudo` 其實是「<font color="red">S</font>uper <font color="red">U</font>ser <font color="red">DO</font>」的縮寫。
如果被加在某一個指令的前面,代表這個指令是透過 Super User 所執行的。
> Linux有非常多指令是用來設定系統環境的
> * 某些伺服器軟體程式,一般則放置到/usr/sbin/當中。
> * 本機自行安裝的軟體所產生的系統執行檔(system binary), 則放置到/usr/local/sbin/當中。
::: danger
#### josh 學長支援網路工具 -> 之後補充
:::
### `/boot` bootstrap
* 放置開機會使用到的檔案,包括 Linux 核心檔案以及開機選單與開機所需設定檔。
- 例如 : `initrd.img`
- Initial ramdisk
- 開機時會先在記憶體中載入一個暫時的根目錄系統
- 包含真正的 `/`
- 掛載真正的 `/` 前的準備工作
- 非必要,但有 `initrd.img`,開機會快很多,因為不用重新編譯 kernel
### `/dev` device
* 存放與設備(如硬碟、USB、終端機等)對應的設備檔案。
- 放置各種硬體設備的檔案
- 因為在 Linux 中,萬物皆檔案,所以對這些硬體檔案做操作就是對硬體做操作
- 例如:滑鼠、鍵盤、記憶體
* 每個檔案都代表一個設備,例如 `/dev/sda1` 代表一個硬碟分區。
* `/dev/tty`:放置終端檔案。
* `/dev/null`:空裝置,也叫做「黑洞」,任何寫入到 `/dev/null` 的資料都會被丟棄,常用來消除不需要的輸出。
* `echo "test" > /dev/null`
:::success
**牛刀小試**
試試看 `cat /dev/sda`(代表第一個硬碟)
:::
### `/etc`
* 系統主要的設定檔,例如網路設定、啟動腳本、服務設定(如 /etc/passwd 保存使用者資訊)。
* 各檔案屬性是可以讓一般使用者查閱的, 但只有 root 有權力修改。
- `/etc/passwd`:user 的帳號密碼檔
- 不用 `sudo` 就可以查看
- 
-  ->第一行
- **帳號名稱**:帳號名稱(例如 root, user)。
- **密碼佔位符**:通常是字母 x,代表密碼儲存在其他地方(例如 /etc/shadow 檔案),並不是明文儲存在這裡。
- 也可以放在`/etc/passwd`,但非常不安全。因`/etc/passwd`是所有使用者和程式都可以讀取的。
- **使用者ID(UID)**:使用者的數字ID(例如 0 是 root 使用者的UID,普通使用者則有自己的 ID 號碼)。
- **群組ID(GID)**:使用者所屬群組的 ID。
- **使用者描述**:使用者的描述資訊,有時是空的。
- **主目錄**:表示該使用者的主目錄位置(例如 /root 或 /home/user)。
- **登入shell**:表示該使用者使用的預設 shell(例如 /bin/bash 或 /usr/sbin/nologin)。
- 小lab:創兩個帳號,把 uid 更改後再回到家目錄看會到哪個帳號
- `/etc/shadow`:真正存 user 密碼的地方
- 需要使用 `sudo` 才能查看
- `shadow` 的密碼是加密過的
- 
1. **使用者名**:每行的第一部分是使用者名(例如 root、sudo)。
2. **加密的密碼**:第二部分顯示加密後的密碼,如果內容不符合加密的輸出格式(例如包含 * 或 ! 等特殊字元),則此使用者就無法登入。
3. **上次密碼變更日期**:第三部分是自1970年1月1日( Unix 紀元時間)以來,上次變更密碼的天數。
4. **最短密碼使用期限**:第四部分表示從密碼變更日起,密碼至少要使用多少天才能再次修改(通常是 0 表示不限制)。
5. **最長密碼使用期限**:第五部分是密碼的最長有效天數,超過此天數後需要更改密碼(例如 99999 表示不強制過期)。
6. **警告期限**:第六部分是密碼即將過期時,提前幾天開始警告。
7. **帳號非活躍天數**:第七部分表示帳號密碼過期後多少天內帳號被標記為不活躍。
8. **帳號過期日期**:第八部分是帳號失效的日期。
9. **保留字段**:第九部分目前通常是保留不使用的。
- [講義 `/etc/passwd`、`/etc/shadow`](https://hackmd.io/LPP9vQ-2TqOvbxpyMjKM3Q)
:::info
**既然有 `/etc/passwd` 了,為什麼還要有 `/etc/shadow`?**
很久以前,`/etc/passwd` 裡面是有存使用者密碼,但那時的加密技術不成熟,而且有很多人把密碼設的很簡單,所以 `/etc/passwd` 的密碼移到 `/etc/shadow` 中並加密。
現在 `/etc/passwd` 的作用主要在察看使用者的資訊,只有 root 才可以看 `/etc/shadow` 。
:::
### `/lib` Library
* 在開機時會用到的函式庫。
* `/bin`或`/sbin`底下的指令會呼叫的函式庫。
* 
:::info
**什麼是 library 函式庫?**
- library 是用在開發軟體的子程式集合
- 生活化的例子:食譜書
- 食譜中的目錄 :point_right: library
- 包含各個食譜 :point_right: 常用的 Function
- 在食譜目錄中選擇麻婆豆腐來料理 :point_right: 在 library 中選擇想要呼叫的 Function
:::
### `/lib<qual>`
* 存放與 /lib 不同的格式的二進位函式庫。
* 如支援 64 位元的 /lib64 函式庫。
### `/media`
* 放置可移除的裝置,例如隨身碟、光碟、DVD。
* 電腦會自動掛載到這裡
* 小精靈(桌面環境中的程式)會幫你偵測設備
* `udisks2` 主要負責管理磁碟和儲存設備的掛載和卸載
:::danger
#### 簡學長支援掛載實作
```shell
(base) bs10081@Reg-labLinux:~$ ls /media/bs10081/Flash-32G/
output.pdf
```
lsblk ->放到指令
sdc 8:32 1 28.8G 0 disk
├─sdc1 8:33 1 200M 0 part
└─sdc2 8:34 1 28.6G 0 part /media/bs10081/Flash-32G
:::
### `/mnt`
* (手動)暫時掛載某些額外的裝置。
:::info
`/media`與`/mnt`
| 目錄 | 目錄內容 |
| -------- | -------- |
| `/dev` | 放置硬體設備的**檔案**|
| `/mnt` | **手動掛載**的可移除裝置|
| `/media` | 放置**自動掛載**的可移除裝置|
:::success
使用 `mount` 命令手動掛載可移除裝置
以下是使用 `mount` 指令手動掛載可移除裝置的步驟:
```bash=
#假設裝置名稱是 /dev/sdb1,並且你希望將它掛載到 /mnt/usb 目錄
sudo mount /dev/sdb1 /mnt/usb
#掛載完成後,你可以檢查掛載是否成功,並查看掛載的檔案系統:
df -h
#這個命令會列出所有已掛載的檔案系統,並顯示它們的掛載點和可用空間。
#你應該能在列表中看到 /mnt/usb 及其對應的裝置 /dev/sdb1。
#卸載裝置
sudo umount /mnt/usb
# 以唯讀模式掛載
sudo mount -o ro /dev/sdb1 /mnt/usb
```
注意:命令是 `umount` 而非 `unmount`,不要拼錯。
:::
### `/opt` optional
* 第三方軟體放置的目錄
* 自行安裝額外的軟體
* 像是 Google Chrome、VirtualBox、telegram
- 怕某個檔案汙染系統的話,可以把雜七雜八的東西放在這裡
* 以前習慣放在`/usr/local`
### `/run`
- 存放系統運行時需要的臨時數據
- 各種服務會需要的暫存檔案
- 例如: `.pid`
- 內容只有一行,紀錄目前的 process 的 id 是多少 (pid)
- 防止同個 service 同時啟動多個副本
- 會導致這些副本互相搶資源
- 啟動服務前會先檢查有沒有 `.pid`
- 有,就停止啟動服務
- 沒有,就啟動服務,然後把此服務的 pid 存進 `<service>.pid`
- 其它同一個 service 的多餘 process 則自動退出
- 當關閉服務時,`<service>.pid` 也會跟著被刪除 (kill)
### `/srv` service
- 放置一些網路服務啟動後,這些服務所需要取用的資料目錄
- 通常有對 Unix 跨平台的服務才會被掛載在這邊
- 例如 : FTP (檔案傳輸協定)
- 用在網路上 client 和 server 之間進行檔案傳輸的應用層協定
- 預設的 FTP server folder 是在 `/srv/ftp` 欲分享的檔案可以放在這邊
### `/tmp`
- 讓一般使用者或者是正在執行的程式暫時放檔案的地方
- 可依照自己的設定來定期清除`/tmp`內的東西
- 
- 所有使用者與群組的權限**可讀可寫可執行**
- 因為 `/tmp` 是讓所有使用者暫存檔案的地方,所以要**可讀可寫**
- 有些程式會將安裝檔暫存在此,所以要**可執行**
- 未經授權的使用者可以寫入惡意程式
- 可能變成病毒的溫床
- 不過可以把特定檔案另外掛載,設定成 ==`noexec`==
- 無法被執行
- 可以避免惡意程式被執行的可能
### `/home`

* 每個使用者都有各自的 home 目錄
* 存放所有使用者的個人檔案和設定檔。
* 每個使用者在 /home 目錄下都有自己的子目錄,這個目錄的名稱通常與使用者名稱相同。
* 使用者名稱為 joanna,那麼該使用者的主目錄路徑就是`/home/joanna`。
* 家目錄的兩種代號:
* ~:代表目前這個使用者的家目錄
* ~XXX :則代表是 XXX 的家目錄
### `/root`
- 系統管理員 (root) 的家目錄
- 一般使用者的家目錄都在 `/home`
- `root` 基本上是 Linux 系統中的神
:::success
`sudo -i` 是用來切換到 root 使用者的命令,並進入該使用者的登錄環境。
:::
### `/lost+found`
* 當檔案系統發生錯誤時, 將一些遺失的片段放置到這個目錄下。
* 使用標準的 ext2/ext3/ext4 檔案系統格式才會產生
:::success
* 用 fsck 程式來檢查檔案系統是否發生**錯誤**
* 跳電 -> 檔案系統格式出問題(bit 跑掉)
:::
### `/proc` process
* 本身是一個『虛擬檔案系統(virtual filesystem)』。
* 存放系統核心、行程資訊(process)、周邊裝置的狀態及網路狀態等。
* 目錄下的資料都存在記憶體中, 所以本身不佔任何硬碟空間。
### `/sys` system
* 也是一個虛擬的檔案系統。
* 不佔任何硬碟空間。
* 記錄核心與系統硬體資訊較相關的資訊。
* 如已載入的核心模組與核心偵測到的硬體裝置資訊等。
## `/usr` 與他的子目錄
- Unix Software Resource,以前是指 user
- 「非系統基本必須的」東西
- Unix 作業系統軟體資源所放置的目錄
User Shareable Read-only 或
Unix System Resources 或
Unix Software Resources 的縮寫
### 需要存在的目錄
- `/usr/bin`
- 放使用者非必備的二進位檔案
- 使用者安裝的程式的指令會在這裡
- `/usr/sbin`
- 非系統平時運作所需要的指令
- 通常給超級使用者使用
- `/usr/lib`
- 不是系統基本的,而是往上安裝的函式庫都放到 `/usr/lib`
- 例如
- `python`:python 的函式庫
- `gcc`:C 的編譯器
:::info
根目錄底下也有`bin`, `sbin`, `lib`?
-

> 根目錄`/`下的`bin`, `sbin`, `lib`與`/usr/`底下的`bin`, `sbin`, `lib`內容是相同的ㄛ
* 目錄底下的重複性高(意義差距不大),因此合併
:::
:::success
#### softlink
* 指向另一個檔案或目錄的指標。
* 類似於 Windows 中的快捷方式。
* 一個獨立的檔案,內容是他所指向的檔案或目錄的路徑。
* 如果原檔案被刪除或移動,軟連結將會無效,成為「死連結」(Broken Link)。
* 通過`ln -s source_file link_name`來建立軟連結。
#### hardlink
* 指向檔案位置,而不是指向檔案名稱。
* 一個檔案可以有多個名稱(即多個硬連結),但它們實際上都指向相同的磁區。
* 硬連結指向檔案的實際數據區塊,因此即使原檔案被刪除,硬連結仍然可以存取該檔案的內容。
* 備份用 hardlink。
* 通過`ln source_file link_name`來建立軟連結。
|項目| 軟連結(Soft Link)| 硬連結(Hard Link)|
|--|--|--|
|位置 |可以跨檔案系統、磁碟分區 |必須在同一檔案系統內|
|刪除原檔案的影響| 刪除原檔案會導致軟連結無效 |刪除原檔案不會影響硬連結|
|指向目標| 指向檔案或目錄的路徑| 指向檔案的數據區塊|
|是否可指向目錄| 可以指向目錄(ln -s)| 通常無法指向目錄(在部分系統中有限制)|
|檔案計數(Links)| 不會增加檔案的硬連結數| 會增加檔案的硬連結數|
* 檔案計數要用 ls -l 看
* 要查看有哪些硬連結指向同一個檔案,可以使用 find 命令:
```bash
find /path/to/search -samefile filename
#這會列出所有指向與 filename 相同檔案數據的連結。
```
:::info
- hardlink 指向一個**檔案本身**
- 史萊姆 -> 一直分裂
- 只是多了一個暱稱,稱呼同一個東西
- softlink 指向**任何東西** -> 他不一定要存在
- 分身 -> 本體沒了就沒了
- 指向一個位置,像是一個指標或是路牌
> [name=蓬萊 人偶] [name=BT]
:::
- `/usr/local`
- 存放系統管理員在本機自行安裝自己下載的軟體
- 將自行安裝的軟體與作業系統的預設軟體區分開來
- 這個子目錄底下也有 `/bin`、`/lib`、`/etc`... 的次目錄
- 當系統進行升級或安裝新發行版時,可以將自行安裝或編譯的軟體放置在這邊
- 避免覆蓋系統預設軟體
- 無須重新安裝全部程式
- 若有相同名稱執行檔,可能會發生系統衝突、混淆(依 $PATH 順序決定)
- `/usr/share`
- 主要放置唯讀架構的檔案
- 幾乎都是文字檔案
- 例如:`man`,線上說明檔案,可以教你指令怎麼用
## `/var` 與他的子目錄
- 主要針對**常態性變動**的檔案
- 系統運作後才會漸漸佔用硬碟容量的目錄
- 快取 (cache)、紀錄檔 (log file) 以及某些軟體運作所產生的檔案
- 適合存放需要頻繁改寫的檔案
- 例如:系統記錄檔、資料庫裡的檔案
### 需要存在的目錄
- `/var/cache`
- 應用程式本身運作過程中會產生的一些暫存檔
- 例如:`apt install` 下來的 package
- `/var/lib`
- 放置程式本身執行的過程中,需要使用到的資料檔案
- 例如:mySQL 的 data base 跟 table 通常都會存在 `/var/lib`
- `/var/lock`
- 某些裝置或者是檔案資源一次只能被一個應用程式所使用
- 同時被兩個程式使用該裝置時,可能產生一些錯誤的狀況
- 所以要將該裝置上鎖 (lock)
- `/var/log`
- 紀錄檔放置的目錄
- `/var/log/auth.log`
- 記錄所有與認證和安全相關的事件,例如登錄嘗試、sudo 使用、SSH 登錄等
- 
- `/var/log/faillog`
- 記錄失敗的登入嘗試,特別是與密碼錯誤相關的事件。
- `/var/log/btmp`
- 紀錄登入失敗的資訊
- `/var/log/wtmp`
- 記錄所有的登錄與登出活動
- `/var/log/boot.log`、 `/var/log/bootstrap.log`
- 開機相關的紀錄檔
- `/var/mail`
- 放置個人電子郵件信箱的目錄
- `/var/spool`
- 這個目錄通常放置一些佇列資料
- 佇列資料 : 排隊等待其他程式使用的資料
- 這些資料被使用後通常都會被刪除
- 例如:印東西<!-- `mail` : 有人寄信過來的時候,信會放在此 -->
- 也有 mail
- 
***
## Linux常用的指令
### 查閱系統指令、工具和功能的說明檔案的工具
| 指令|簡介|
|-|-|
|man|Manual,用來查閱系統中每個命令或程式的手冊|
|info|命令提供了比 `man` 更詳細、更結構化的檔案說明|
|whatis|更簡潔的指令說明,它只會返回一行簡短描述|
|type|查詢某個指令的型態|
|file|確定檔案型態|
|uname|顯示有關 Linux 系統基本資訊|
```bash=
man ls # 查看 ls 命令的手冊頁
<--ls 命令的手冊頁(下略)-->
info ls # 查看 ls 命令的 info 文檔
<--ls 命令的 info 文檔(下略)-->
whatis ls # 返回一行描述 ls 命令的功能
ls (1) - list directory contents
LS (6) - display animations aimed to correct users who accident...
type ls # 查詢 ls 命令的型態
ls is alias to 'ls --color=auto'
file /bin/ls # 確定 /bin/ls 的檔案型態
/bin/ls: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2,
BuildID[sha1]=36b86f957a1be53733633d184c3a3354f3fc7b12, for GNU/Linux 3.2.0, stripped
uname #顯示有關 Linux 系統基本資訊
Linux
uname -a #顯示詳細系統資訊
Linux leafish 5.15.153.1-microsoft-standard-WSL2 #1 SMP Fri Mar 29 23:14:13
UTC 2024 x86_64 x86_64 x86_64 GNU/Linux
```
### 常用的網路相關工具
| 指令|簡介|
|-|-|
|netstat|查看系統的網路連接和統計數據|
|ss|現代化的 socket 統計工具,替代 `netstat`,顯示網路連接、監聽port等|
|dig|DNS 查詢工具,用於獲取域名的 DNS 資訊|
|ping|測試網路連通性,檢測主機是否可達並計算延遲時間|
```bash=
netstat -an # 顯示所有連接並以數字格式顯示
netstat -r # 顯示路由表
ss -tuln # 顯示所有 TCP、UDP 監聽端口,以數字格式顯示
ss -p # 顯示與連接相關的進程
dig example.com # 查詢 example.com 的 A 記錄(IPv4 地址)
dig google.com MX # 查詢 google.com 的 MX 記錄(郵件交換器)
dig @8.8.8.8 example.com # 使用 Google 的 DNS 伺服器(8.8.8.8)查詢
ping example.com # 向 example.com 發送 ICMP 數據包,測試連通性
ping -c 4 google.com # 向 google.com 發送 4 個 ICMP 數據包
```
### 操作檔案相關的指令
| 指令|簡介|
|-|-|
|pwd|<font color="red">p</font>rint <font color="red">w</font>orking <font color="red">d</font>irectory 顯示當前目錄位置|
|ls|<font color="red">l</font>i<font color="red">s</font>t 將當前目錄底下的檔案列出來<br>|
|cd|<font color="red">c</font>hange <font color="red">d</font>irectory 切換路徑|
|mkdir|<font color="red">m</font>a<font color="red">k</font>e <font color="red">dir</font>ectory:建立資料夾|
|touch|新增檔案:touch 檔名.副檔名|
|cat|~~貓~~ 正確解釋:con<font color="red">cat</font>enate, 但我比較喜歡:call at terminal的說法|
|head|用來顯示檔案的**前面幾行**,預設顯示 10 行|
|tail|用來顯示檔案的**最後幾行**,預設顯示 10 行|
|more|用來**分頁顯示**檔案內容的命令,適用於顯示較大的檔案|
|less|類似 more,但可以上下滾動並支援搜索功能,更靈活|
|cp|<font color="red">c</font>o<font color="red">p</font>y :要被複製的檔案路徑 複製檔的檔案路徑|
|rm|<font color="red">r</font>e<font color="red">m</font>ove|
|rmdir|<font color="red">r</font>e<font color="red">m</font>ove <font color="red">dir</font>ectory ([與 `rm -r ` 差異](https://teamtreehouse.com/community/rm-r-vs-rmdir))|
|mv|<font color="red">m</font>o<font color="red">v</font>e|
### pwd 顯示當前目錄位置
<font color="red">p</font>rint <font color="red">w</font>orking <font color="red">d</font>irectory <br>
***
### ls 將當前目錄底下的檔案列出來
<font color="red">l</font>i<font color="red">s</font>t

開頭為`.`的為隱藏檔案,使用`ls -a`即可看到
->想看到更多詳細資訊,用`ls -l`顯示詳細資訊
->組合技`ls -la`,顯示詳細資訊+隱藏檔案
**其中含義**

1. `白色` **檔案類型與權限(Mode)**:第一個字元表示檔案的類型:
* -:一般檔案(regular file)
* d:目錄(directory)
* l:符號連結(symbolic link)
* b:區塊設備檔案(block device file)
* c:字元設備檔案(character device file)
2. `紅色` 隨後的 9 個字元分為 3 組,分別表示檔案擁有者、群組、其他使用者的讀取、寫入與執行權限:
* r:讀取權限(read)
* w:寫入權限(write)
* x:執行權限(execute)
3. `橘色`**連結數量(Links)**: 顯示這個檔案或目錄的連結數量。
4. `黃色`**擁有者(Owner)**: 檔案的擁有者名稱。
5. `綠色`**群組(Group)**: 檔案所屬的群組名稱。
6. `藍色`**檔案大小(Size)**: 檔案的大小,以位元組(bytes)為單位。
7. `粉色`**最後修改時間(Timestamp)**: 檔案最後修改的日期和時間。格式為月、日和時間。如果修改時間超過一年,會顯示年份而非時間。
8. `紫色`**檔案名稱(Name)**: 檔案或目錄的名稱。如果是符號連結,會顯示連結到的目標。
:::info
#### 檔案時間參數
* mtime(modification time)
* 當該檔案的『內容資料』變更時,就會更新。
* ctime(status time)
* 當該檔案的『狀態 (status)』改變時,就會更新這個時間
* 像**權限**與**屬性**被更改了,都會更新這個時間。
* atime(access time)
* 當『該檔案的內容被取用』時,就會更新這個讀取時間 (access)。
* 像使用 cat 去讀取,就會更新該檔案的 atime 。
:::
* `ls -r`: 以反向排序列出檔案
* `ls -R`: 列出目錄下所有檔案,包含目錄下的資料夾內的所有檔案
* `ls -t`: 依照檔案建立時間列出
* `ls -S`: 依照檔案大小排序
:::success
#### 牛刀小試
試試`ls -rRts`?
:::
***
### chmod 更改檔案或目錄權限
chmod 命令用來更改檔案或目錄的權限(讀取、寫入、執行)。
權限模式:
- `r`:讀取權限(4)。
- `w`:寫入權限(2)。
- `x`:執行權限(1)。
```bash=
chmod 755 filename # 將權限設為 rwxr-xr-x(所有者可讀寫執行,群組和其他人可讀執行)
# 每個權限使用一個數字來表示,三位數分別代表所有者、群組、其他人的權限,權限位可以疊加。
chmod u+w filename # 給檔案擁有者增加寫入權限
```
權限分為所有者(user)、群組(group)、其他人(others)三類。
:::info
如果你執行
```bash=
ls -ld /tmp
```
你應該能看到類似這樣的輸出:

注意最右邊的有個 t,這叫做 sticky bit,一種特殊的 bit,它的主要作用是限制檔案的刪除權限。
**Sticky Bit 的作用**
當 sticky bit 被設定在一個目錄上時,該目錄內的檔案和子目錄只能由以下幾類使用者刪除或重命名:
- 檔案的所有者。
- 目錄的所有者。
- root 超級使用者。
即使其他使用者擁有該目錄的**寫入(read)權限**,他們也不能**刪除或修改他人建立的檔案**。這在像 `/tmp` 這種目錄中特別有用,因為它可以防止使用者之間相互刪除檔案。
**這種權限被設定成 `1777`**
:::
### chgrp 改變所屬群組
要被改變的群組名稱必須要在`/etc/group`檔案內存在。
```bash=
chgrp mygroup filename # 將檔案的群組所有權改為 mygroup
```
### chown(Change Owner)
`chown` 命令用來更改檔案或目錄的所有者和/或群組。
```bash=
chown myowner filename # 將檔案的群組所有權改為 mygroup
```
### adduser & useradd
`adduser` 和 `useradd` 兩個都是用來新增使用者的命令,雖然功能相似,但還是有些不同。
- `adduser`
是功能比較多的命令,它會自動建立家目錄、設定密碼等。
- `useradd`
需要手動設定選項。它不會自動建立家目錄或設定密碼。
```bash=
sudo adduser newuser # 添加新使用者 newuser
sudo useradd -m newuser # 創建新使用者並自動創建家目錄
# 通常會搭配 passwd 命令來設定新使用者的密碼:
sudo passwd newuser
```
### UID、GID 概念
- **UID(User Identifier)**:在 Linux/Unix 系統中,每個使用者都有一個唯一的使用者ID(UID)。這是系統用來識別每個使用者的方式。
- UID 0 通常是root(超級使用者)。
查看某個使用者的 UID:
```bash=
id -u username # 查看使用者 username 的 UID
```
- **GID(Group Identifier)**:每個群組都有一個唯一的群組ID(GID)。檔案的群組所有權由其 GID 來決定。
查看某個使用者的 GID:
```bash=
id -g username # 查看使用者 username 的 GID
```
查看檔案的 UID 和 GID:
```bash=
ls -l filename # 列出檔案的詳細信息,包括所有者 UID 和群組 GID
```
:::info
- 小 LAB
- `vim printUid.c`
- ```c=
#include <stdio.h>
#include <unistd.h>
int main() {
printf("The uid is: %d\n", geteuid());
return 0;
}
```
- `sudo apt install gcc`
- `gcc printUid.c -o printUid`
- `./printUid`
- `sudo chown root printUid`
- `sudo chmod 4755 printUid`
- `./printUid`
:::
***
:::spoiler cd 切換路徑
### cd 切換路徑
<font color="red">c</font>hange <font color="red">d</font>irectory

* `cd ..`:可以回到上一個目錄
* `cd .`:當前目錄
* `cd -`:前一個工作目錄
* `cd ~`: 當前 user 的家目錄, 直接下 cd 也可以回家目錄
***
:::
### mkdir 建立資料夾
<font color="red">m</font>a<font color="red">k</font>e <font color="red">dir</font>ectory

***
### touch 新增檔案

::: info
**文字編輯**
#### nano
指令`nano <檔名>.txt`進入文字編輯,開始撰寫內容。
要離開的話,下方已經很好心的提示我們怎麼離開:^X Exit
> 這邊的 ^ 是 ctrl 的意思,在 linux 環境裡面是很常見的縮寫方式。

按下 ctrl + X 之後,nano 會提示是否要存檔,依據指示設定存檔格式之後,就可以看到剛剛建立的檔案了。
---
#### vim
指令`vim <檔名>.txt`,進入vim。
vi 共分為三種模式,分別是『一般指令模式』、『編輯模式』與『指令列命令模式』。
- 一般指令模式 (command mode):一打開就直接進入(預設模式),可以刪除、複製、貼上檔案內的文字,無法編輯檔案內容。
- 編輯模式 (insert mode):在一般模式當中,輸入『i, I, o, O, a, A, r, R』後才會進入編輯模式,離開時按Esc即可回到一般指令模式。
- 指令列命令模式 (command-line mode):在一般模式當中,輸入『 : ,/, ? 』三個中的任何一個按鈕進入指令列命令模式,對檔案進行讀取、存檔、大量取代字元、離開 vi 、顯示行號等等的動作。
:::spoiler 三種模式關係圖

[圖鏈來源](https://linux.vbird.org/linux_basic/centos7/0310vi.php)
:::
***
### cat 印出檔案內容
con<font color="red">cat</font>enate

***
### head 顯示檔案的前面幾行
head 命令用來顯示檔案的前面幾行。
預設情況下,head 顯示檔案的前 10 行,但可以使用選項來指定顯示的行數。
```bash=
head filename.txt # 顯示前 10 行
head -n 5 filename.txt # 顯示前 5 行
```
***
### tail 顯示檔案的最後幾行
tail 命令用來顯示檔案的最後幾行。
與 head 相似,預設顯示最後 10 行,並可透過選項調整顯示行數。此外,tail 還可以持續監控檔案末尾的變動,常用於日誌檔案的實時監控。
```bash=
tail filename.txt # 顯示最後 10 行
tail -n 20 filename.txt # 顯示最後 20 行
tail -f logfile.log # 實時監控檔案的變動(常用於監控日誌)
```
***
### more 分頁顯示檔案內容
more 是一個用來分頁顯示檔案內容的命令,適用於顯示較大的檔案。
它會一次顯示一頁的內容,按空格鍵可以繼續往下看,但只能從上往下查看,不能返回。
```bash=
more filename.txt
```
- 按下 `空格鍵` 向下翻一頁。
- 按下 `Enter` 向下翻一行。
- 按下 `q` 退出。
***
### less 上下滾動查看檔案內容
less 命令功能與 more 相似,但比 more 更加靈活。less 可以上下滾動查看檔案內容,並且不需要一次將整個檔案加載到內存中,因此在查看大檔案時非常有效率。
```bash=
less filename.txt
```
- 使用 `Page Up` 和 `Page Down` 進行翻頁。
- 使用 `q` 退出。
- 搜尋功能,按下 `/` 鍵後輸入搜尋字串,並按 `n` 查找下一個。
***
### cp 複製檔案
<font color="red">c</font>o<font color="red">p</font>y :要被複製的檔案路徑 複製檔的檔案路徑 (source to destination)

* `cp -r`:複製資料夾(r = recursive)
* `cp -p`: 連同檔案的權限、擁有者、時間都複製 -> 常用於備份
***
### mv 移動檔案(剪下貼上)/重新命名
<font color="red">m</font>o<font color="red">v</font>e

***
### rm 刪除檔案
<font color="red">r</font>e<font color="red">m</font>ove

* `rm -r`:刪除資料夾(r = recursive)
* `rm -rf`:可<font color="red">強制</font>刪除檔案,<font color="red">要小心使用!</font>
:::danger
**摧毀系統(電腦)的指令**
```bash=
rm -rf --no-preserve-root /
```
沒試過,但感覺很酷:D
:::
> `rmdir`與`rm -r`的差異:
> `rmdir` only works if the folder is empty. `rm -r` will remove the folder and everything inside of it.
***
### echo 將字串輸出到終端上

* `echo -n`:不換行
* `echo *.副檔名`:印出所有的‘.副檔名‘檔案
* 使用指令 `echo $PATH` 印出 PATH 環境變數
* path:系統要到哪些路徑底下找執行檔
* 內容全部都是路徑,每個路徑之間用分號( ; )隔開
* 
* 使用指令 `echo $$` 印出當前 shell 的 pid (process id)
:::info
在前面我們有提到
> 每個執行的Process都被表示為檔案,可以在/proc目錄下找到相應的檔案,如/proc/{PID}/status和/proc/{PID}/cmdline。
那我們在的終端機裡打指令,終端機也會有一個 pid,而查看當前終端機 pid 的方法就是`echo $$`
除此之外,在 Linux/Unix 系統中,`top` 和 `ps` 則是可用來監控和管理 process 的兩個重要工具
**top** 的主要功能:
- 顯示系統當前狀態:包括 CPU 使用率、RAM 使用情況、正在運行的 Process 數量等
- 動態更新:每隔幾秒鐘(預設是 3 秒)自動更新
- 按需排序和篩選:可以根據 CPU 使用率、RAM 使用等指標排序,查看最消耗資源的 Process
- 與 Process 交互:可以直接在 `top` 界面中發送信號(如 `kill`)來終止Process。
**ps** 只會顯示命令執行時的系統狀態(靜態),不會持續更新
**ps** 的主要功能:
- 列出 Process 狀態:包括 Process 的 PID、狀態、CPU 和 RAM 使用等。
- 靜態輸出:與 `top` 不同,`ps` 是靜態的,顯示當前某一刻的系統狀態,不會自動刷新。
- 過濾和篩選進程:可以通過各種選項篩選、過濾或格式化輸出 Process 資訊。
```bash=
ps aux # 列出所有進程的詳細信息
ps -ef # 顯示進程的完整格式
ps -u username # 列出特定使用者的進程
ps -p PID # 顯示特定進程的詳細信息
```
:::
***
### history 顯示用戶執行過的命令歷史
```bash=
history
```
### sl
- 重要套件
- 會考會考歐
```bash
sudo apt install sl
```
***
:::spoiler df -h
### df -h
-> zfs
截ext4的圖
介紹欄位、意思,尤其是**mount on**
哪個partition掛在哪個掛載點
->較好去修復壞掉的儲存裝置

- 有隨身碟掛載點
- 有 nfs
- Synology NAS to Ubuntu with ZeroTier One(VPN)
- 所以 IP 才會是 `192.168.193.64`,可自己設定
:::
:::spoiler lsblk
### lsblk

:::
:::spoiler 需補的指令
需補的指令
* su ->重要!
* grep->(簡單的)正規表達式 ->蓬萊人偶
* alias
* awk
* mktmp
* ^r:搜尋之前用過的指令
* suid、sgid ->小lab一起->sticky bit一起提
需補參數
* \>、>> ->蓬萊人偶
stdin、stdout、stderror
:::
:::info
好康的分享
- Ubuntu Dock like Windows(點一下左邊應用程式圖示(Ex. Firefox)可以打開和最小化視窗)
[name=RegChien]
`gsettings set org.gnome.shell.extensions.dash-to-dock click-action 'minimize'`
:::
:::danger
助教的筆記
1. /boot 是 bootstrap?
電腦自己會載入/boot再找到映像檔(?
2. inode 1 是什麼?為什麼root不是1?
保留給虛擬檔案,指到1的都沒有儲存在硬碟上

[資料來源](https://ext4.wiki.kernel.org/index.php/Ext4_Disk_Layout#Special_inodes)
[資料來源2](https://unix.stackexchange.com/questions/198673/why-does-have-the-inode-2)
3. inode怎麼教?
在ls教
4. cd 是builtin,why?
改變pwd,切換環境(working directory)
5. `sudo -i` 為什麼是打使用者的密碼,那這樣大家都打各自的密碼都能到root?
要有sudo權限才可以(創使用者時可將該使用者拔除sudo權限)
6. 救援檔案->檔案會存在硬碟內(資料沒有被馬上刪除)->mtime影響
7. etc/skel -> 放骨架。創建新使用者時,此檔案內的資料會一併複製到新使用者家目錄。
:::