---
# System prepended metadata

title: LSA （二） A review of Linux SysAdmin 濃縮系統管理相關知識技能、RPi 實做

---

# LSA （二） A review of Linux SysAdmin 濃縮系統管理相關知識技能、RPi 實做

[TOC]
## 硬碟
- ![](https://hackmd.io/_uploads/r16sGURVh.png)
- 硬碟等於放置回憶的記憶區塊
- 與記憶體不同的點在於，主記憶體是提供目前要思考與處理的資訊，但瑣事或沒有要立刻處理的事，就會先放入硬碟。
- 硬碟的資料是讀寫在磁碟盤中
### 傳統硬碟 (Hard Disk Drive, HDD) ＆ 固態硬碟 (Solid State Disk, SSD)


|          HDD           |           SSD            |
|:----------------------:|:------------------------:|
|          便宜          |           較貴           |
|        容量較大        |         容量較小         |
| 故障救回資料的機會較大 | 故障後救回資料的機會較低 |
|      怕碰撞與晃動      |     較不怕碰撞與晃動     |
|          耗電          |           省電           |
|     運轉時噪音較大     |         較無噪音         |
|       讀寫速度慢       |        讀寫速度快        |


## FHS

### 基本介紹
- FHS 全名：Filesystem Hierarchy Standard（檔案系統階層標準）
- 定義：定義 Linux 系統中，所有目錄及子目錄架構及目錄內容
- 目的：讓使用者瞭解已安裝的軟體通常是放在哪個目錄下
### FHS 架構
![](https://hackmd.io/_uploads/HkB2xSJS2.png)
> photo from: [照片來源](https://hackmd.io/@ncnu-opensource/book/https%3A%2F%2Fhackmd.io%2FPubDEY-tSKuAsszd1xiK1w%3Fview)
- `/` (根目錄)：Linux系統中最重要的目錄，是所有目錄的根源
![](https://hackmd.io/_uploads/rJQ6erkS2.png)
    - 比喻成樹木的話，即為所有分支的源頭
    - 開機、還原、系統修復等動作皆與根目錄有關
    - 根目錄可以分配小一點，避免空間過大被塞入其他資料，保持其高效能及避免發生錯誤

- `/bin`  = binary：放一些一般使用者可以操作的指令
![](https://hackmd.io/_uploads/H1m0lHyr2.png)
    - `bin` 底下的指令可以被 root 與一般帳號所使用
    - ex：`cat`、`chmod`、`mkdir` 等指令
- `/boot` = bootstrap：放置系統開機時會使用的相關載入檔
![](https://hackmd.io/_uploads/BkJ1Zr1Bh.png)	
    - `initrd.img`：小的暫時的 root file system，用於全新安裝，crash急救，網路開機等時候
- `/dev` = device：任何硬體裝置與周邊設備的相關資料，都以檔案型態儲存在`/dev`中
![](https://hackmd.io/_uploads/SJ21ZHJSn.png)
    - ex：鍵盤、滑鼠等
- `/etc`：放置系統主要的設定檔案
![](https://hackmd.io/_uploads/rk2e-HJH2.png)
    - 通常一般使用者可以查看此目錄中的檔案，但只有 root 可以修改
    - `/etc/passwd`：使用者資訊，一般使用者就可以查看
    ![](https://hackmd.io/_uploads/HJS-WSyH3.png)
        - 使用者名稱
        - 加密的密碼
        - 使用者 ID 號碼 (UID)
        - 使用者的群組 ID 號碼 (GID)
        - 使用者資訊
        - 使用者起始目錄
        - 登入 shell
    - `/etc/shadow`：放置使用者密碼，原理是將 `/etc/passwd` 的檔案加密移至 `/etc/shadow` ，且只有 root 可以查看，防止破譯
    ![](https://hackmd.io/_uploads/HyYMbr1Hh.png)
        - 使用者名稱
        - 密碼：已加密
        - 上次密碼變更日期
        - 密碼最短使用期限：表示變更密碼之後，如果還要更改密碼，必須等的時間，單位為天
            - 若此欄位為空白或 0，表示停用此功能，無需等待。
        - 密碼最長使用期限：表示一組密碼最久可以使用的時間，然後就要更改密碼，單位為天
            - 密碼過期後，仍可以使用，但在下次登入時，系統會要求使用者立即變更密碼
            - 若此欄位是空的，則代表停用此功能
            - 若此欄位為 99999 表示密碼不需要重新設定
        :::info
        - 若密碼最長使用期限的值小於密碼最短使用期限，則此使用者就會不能更改自己的密碼。
        :::
        - 密碼需要變更前的警告：上例7 表示 7 天內系統會警告帳號。
        - 密碼過期的恕限時間：當密碼失效後，n 天內還可以登入。
        - 帳號失效日期：計算方式同欄位 3。
        - 保留：看以後有無新功能加入。
    - `/etc/group`：放置關於系統管理員對使用者和使用者群組管理文件
        ![](https://hackmd.io/_uploads/B1H7-r1r3.png)
        - 組名：不可重複
        - 口令：存放使用者群組加密後的口令，通常一般群組不會有口令（空白或 x ）
        - 群組 ID
        - 群組內使用者列表
    - `/etc/securetty`：控制哪些終端允許 root 登入
    - 之前學的 web server：apache2、nginx、lighttpd 檔案也在 `/etc` 目錄中
- `/home`：系統預設的使用者家目錄
![](https://hackmd.io/_uploads/rJM4ZHyBn.png)
    - 新增一個使用者帳號時， 預設的使用者家目錄都會規範到這裡
    - 代號：
        - `~` 目前使用者的家目錄
        - `～ <使用者名稱>` 此使用者的家目錄
- `/lib` = Library：主要為系統函式庫和核心函式庫
![](https://hackmd.io/_uploads/S13EWr1rh.png)
    - ex：開機時使用的函式庫， 
    - `/bin` 或 `/sbin` 底下指令會呼叫的函式庫
- `/media`：放置可以移除的自動裝置掛載目錄
![](https://hackmd.io/_uploads/SyiHZrkBn.png)
    - ex：軟碟、光碟、DVD
- `/mnt`：為管理員、使用者手動掛上（mount）的目錄
![](https://hackmd.io/_uploads/BJd8bBJSn.png)
    - 暫時掛載某些額外的裝置建議掛載在此目錄中
    - 與 `/media` 不同的是，`/mnt` 需要系統管理員手動掛載至目錄
- `/opt	`：放置第三方軟體的目錄
    - ex：chrome
- `/root`：放置系統管理者的家目錄
- `/sbin`：放置開機過程中所需要的指令，像是開機、修復、還原系統所需要的指令
![](https://hackmd.io/_uploads/By7PbHkrh.png)
    - 只有系統管理員可以使用的指令
    - ex：reboot、shutdown
- `/srv`：放置一些網路服務啟動後所需取用的資料目錄
![](https://hackmd.io/_uploads/rkTvWrJrh.png)
    - ex：WWW 伺服器需要的網頁資料就可放置在 `/srv/www/`
    - ex：`/srv/ftp`
- `/tmp`：放置暫存檔案 (雜七雜八的東西)
![](https://hackmd.io/_uploads/Hkd_ZHJBn.png)
    - 需要定期清理
    - 不適合放重要資料，因開機時通常 `tmp` 的資料會刪除
- `/run`：放置系統開機後所產生的資訊
![](https://hackmd.io/_uploads/BkxY-SJr3.png)
    - 因可使用記憶體模擬方式，所以效能較好
#### `/usr` 及其子目錄
- `/usr`： Ｕnix software resource 縮寫，放置 Unix 作業系統軟體資源，相關軟體、服務等，非使用者資料
![](https://hackmd.io/_uploads/H1qtZByHn.png)
    - 安裝時此目錄會佔用最多磁碟容量
- `/usr/bin`：放置一般使用者能夠使用的指令
![](https://i.imgur.com/ZJ0VuA7.png)
    - 此目錄下不能再有子目錄
    - 目前已與`/bin` 合併
:::warning
#### 為什麼需要有 `/usr/bin` ?
- `/bin` 和 `/usr/bin` 是於 2021 Feb 合併
- 合併前 `/usr` 意思非 Unix software resource，而是 user
    - 原始目錄目的：在一開始開發的時候，使用的是 1.5 MB 的 disks，後來當這個硬碟滿了後，才創建 `/usr` 目錄
    - `/bin` 放置的是系統必備的二進位檔案，且需要在 `/usr/bin` 安裝前就可以使用
    - `/usr/bin` 放置的檔案包含系統核心操作的非必備檔案，像是一些應用軟體工具的執行黨
        - ex：c++、gcc
- 可以使用以下指令在 Uduntu 中查詢 `/bin` and `/usr/bin` 的意思
    - `man hier | grep -E '/bin$|^.{7}(/bin)' -A2`
        > `-A<行數>`：除了顯示要的行列內容外，也顯示該行後的內容
    - `/bin`：This directory contains executable programs which are needed in single user mode and to bring the system up or repair it. 
        - 此目錄包含單用戶模式時，系統啟動或修復時所需的執行檔案。
    - `/usr/bin`：This is the primary directory for executable programs. Most programs executed by normal users which are not needed for boot. 
        - 多為普通用戶使用且不需要啟動的檔案
:::
:::info
#### 什麼是正規表達式？
- 正規表達式 / 常規表示法（Regular Expression, RE）
- 透過一些特殊字元的排列，用來『搜尋/取代/刪除』一列或多列文字字串， - 是一種字串處理的表示方法表示式
- 並非是工具程式，而是字串處理的標準
- 如果要用正規表達式處理字串的話，需要使用正規表達式的工具程式
    - ex：grep, sed, awk...

#### 為什麼要用正規表達式？
- 在日常生活中就很常需要使用到，例如我如果要搜尋 Mail，但如果我是在沒有使用正規表達式的環境尋找的話，搜尋結果可能會包含 Mail, mail, MAil, maiL...
    - 會搜尋到許多不是目標字串的字串，造成使用困擾
- ex: 當我開機時，我都會發現有個關於 mail 的錯誤訊息，我目前已知的事開機過程的相關程序是在 `/lib/systemd/system/` 底下
    - 如果沒有使用正規表達式
        - 可能就需要在 `/lib/systemd/system/` 目錄下，將檔案一個個開啟，然後去搜尋 mail 這個關鍵字，很不方便
    - 如果使用正規表表達式
        - 可以用一個指令找出 `grep 'mail' /lib/systemd/system/*`
        - 很便捷且簡單

- 正規表示法對系統管理員很重要，幾乎是不可不學的
    - 系統管理員需要很多的訊息資料
    - 使用正規表示法可以省事很多

#### 延伸正規表示法
- `grep -E` or `egrep`
- 可以簡化指令
    - ex: 要顯上檔案內容，但不要顯示檔案內的空白行與行首為 # 的行列
        - 正規表示法：`grep -v '^$' /etc/rsyslog.conf | grep -v '^#'`
        - 延伸正規表示法：`egrep -v '^$|^#' regular_express.txt`
:::
:::info
#### 什麼是 single user mode？
- 單用戶模式（single user mode）, 維護模式（maintenance mode）, or 啟動模式 1（runlevel 1）
- 為 Linux 系統的一種操作模式
    | runlevel                | 意涵    |
    | -------------------- | ---- |
    | 0 (halt)             | 系統關機，如果將 RunLevel 設為  0，則會發現當開機程式完成後系統就直接關機。     |
    | 1 (Single user mode) | 單人模式，通常在系統發生問題需要維護時才會進入此一模式。     |
    | 2 (Multiuser without NFS) | 多人模式但沒有 NFS 網路功能，通常用於多人多工但不需要網路功能時，才會進入此模式     |
    | 3 (Full multiuser mode) | 多人文字模式，此模式為不需要進入視窗模式，並且具備完整網路功能的管理者所使用的模式     |
    | 4 (unused)    | 尚未使用，使用者可以自行定義     |
    | 5 (X11)           | 多人圖形模式，此模式為習慣使用視窗模式，並且具備完整網路功能的管理者所使用的模式     |
    | 6 (reboot) | 重新啟動，若您將 RunLevel 設為此模式則會發現當開機程式完成後，系統就直接重新啟動 |
- 只提供少數服務及功能
- 通常此模式只有在系統發生問題需要維護的時後才進入此模式
- 一種擁有超級使用者權限的模式
- 使用 `fsck` 修復損壞的文件系統
- 另一個用途
    - 如果電腦啟動了卻不允許用戶登錄，可能是因為使用了不正確的密碼
    - 當這種狀況發生時，可以使用單用戶模式更改密碼並重新啟動系統
:::
- `/usr/lib`：與 `/lib` 功能相同
![](https://i.imgur.com/zw8WsQI.png)

    - 目前已與 `/lib` 合併
:::warning
#### `/lib` 與 `/usr/lib` 的差異
- `/lib` 放置的是 `/bin` 或 `/sbin` 函式庫，主要是系統運行所需的函式庫
- `/usr/lib` 放置的是 `/usr/bin` 和 `/usr/sbin` 的函式庫，多為系統的普通使用的函式庫
:::
:::info
#### 什麼是函示庫？
- 就像是一群已經寫好的 Function 包起來變成一個 Library，當我要使用這個 Function 時，我們只需要 import 包含這個 Funtion 的 Library。
- 例子：如果我們要做高登食譜裡的糖醋排骨，我們只需要在高登食譜中的目錄中去目錄中尋找糖醋排骨，在根據裡面的食材和步驟做糖醋排骨。
    - 目錄就等於 `lib`，食材及步驟等於 Function
:::
- `/usr/sbin`：放置非系統正常運作所需要的系統指令
![](https://i.imgur.com/gSHw8DK.png)
    - 目前已與 `/sbin` 合併 
    - 給 super user 使用
    
:::warning
#### `/sbin` 與 `/usr/sbin` 的差異
- 合併前
    - `/sbin` 放置系統管理員必備，但是一般用戶不會使用的二進制文件
    - `/usr/sbin`：放置非系統管理員必備的工具
        - 網絡管理 command，ex：httpd、imap
-  可使用以下指令在 Uduntu 中查詢 `/sbin` and `/usr/sbin` 的意思
    - `man hier | grep -E '/sbin$|^.{7}(/sbin)' -A2`
- `/sbin`：Like `/bin`, this directory holds commands needed to boot the system, but which are usually not executed by normal users. 只有 super user 可執行且系統必備的檔案，非一般使者執行的檔案。
- `/usr/sbin`：This  directory contains program binaries for system administration which are not essential for the boot process, for mounting.
:::
:::info
#### 什麼是二進位檔案？
- binary file 
- 電腦檔案分為 binary file 和 ASCII（純文字檔案）
- 二進位檔是將資料以二進位的格式儲存，例如影像檔或執行檔
    - 一般文書處理軟體並不能處理二進位檔，如果以記事本開啟二進位檔，只會出現一堆亂碼
- lib64，支援 64 位元的函式庫；lib32，支援 32 位元的函式庫
:::
:::info
#### 什麼是掛載？
- 在 Linux 系統中，掛載是一個非常重要且使用頻繁的功能
- 將一個設備掛接到一個已存在的目錄上
- 將硬碟中的檔案連接到系統的某個位置
- 因為在 Linux 中，萬物皆檔案，因此硬體裝置也是檔案，因此我們也可以說，如果我們要使用這個裝置，我們需將 Linux 本身的檔案目錄與硬體裝置的檔案目錄「合二為一」，這個「合二為一」就是掛載
- ex: 在本機安裝一台光碟機，這台光碟機就會掛載在 /dev 裡面
:::
- `/usr/local`：放置管理員自行安裝的軟體（非系統預設提供的），方便管理
![](https://i.imgur.com/IJXOk6Z.png)
    -  此目錄下也有 `/bin` 、`/etc` 、`/include` 、`/lib` 等目錄
    -  可以與原先系統提供軟體版本做區分
:::warning
#### `/usr/local/bin`、`/usr/local/sbin` 及 `/usr/local/lib` 
- `/usr/local` 放置的是使用者自己安裝的應用程式相關檔案，非操作系統本身的檔案
- 下載應用軟體或編譯原先軟體的檔案後，編輯後的 `./configure` 系統通常會預設 `prefix` 至 `/usr/local` 
    - `./configure --prefix/usr/bin/`
    - `/usr/local/bin` 儲存以上軟體的一般使用者執行檔案
    - `/usr/local/lib` 放置`/usr/local/bin` 的函式庫

:::
:::info
#### 什麼是 prefix ?
- The --prefix=PREFIX option installs architecture independent files in PREFIX . When you run a make install command, libraries will be placed in the PREFIX/lib directory, executables in the PREFIX/bin directory and so on. If this argument is not passed to the configure command then the default value is /usr/local
- prefix = 配置安裝路徑
- 可以使用 prefix 指定：`./configure --prefix=/usr/lcoal/test`
    - 相關的檔案就會都放在 `/usr/lcoal/test` 就不會雜亂
- 使用 prefix 的優點是，如果要刪除應用軟體時，只需要簡單的刪除安裝目錄就可以刪乾淨
- 可以與其他原先檔案做區隔，較不會污染其他目錄
:::
:::info
#### PATH
- PATH 環境變數
- `export` 環境變數
- `export | grep PATH`
- `export PATH="./:$PATH"` 改變 PATH
- `cat .bashrc`
:::
- `/usr/share`：放置唯讀架構的資料檔案
![](https://i.imgur.com/HOdckJI.png)

    - 基本上都是文字檔案
    - ex：`man` 、`doc` 、`zoneinfo`
#### `/var` 及其子目錄
- `/var` = variable：記載著各種系統上的變數的地方，針對常態性變動的檔案
![](https://i.imgur.com/By5wGub.png)
	
    - 系統開始運行後，會漸漸開始佔用硬碟容量
- `/var/cache`：放置程式本身運作過程中會產生的一些暫存檔
![](https://i.imgur.com/u8IbHG9.png)
    - `/var/cache/apt`：放置apt 命令安裝的 package
        - 下載過程時會先儲存在 `/var/cache/apt/archives/partial` 中
        - 下載完畢後，會被轉移至 `/var/cache/apt/archives` 目錄中
    - 如果需要重新下載應用程式，系統會在此目錄中尋找並獲取暫存黨，不需要重新安裝，節省安裝時間

- `/var/lib`：放置程式運作過程中需要使用到的資料檔案
![](https://i.imgur.com/xSLgU8y.png)
:::warning
#### About `/var/lib`
- `/var/lib` and `/usr/lib` have a similar purpose.
- Cause `/var` is variable so the directory in `/var/lib` is writable.
- The `/usr` directory which is often required to be read-only.
- ex: 如果我使用 MySQL，我的 MySQL 函式庫檔案會放在 `/usr/lib`，但我需要寫入 MySQL 的資料庫會放在 `/var/lib`，且資料庫內容會因為寫入而一直變更
:::
- `/var/lock`：放置被上鎖的檔案
![](https://i.imgur.com/BQoc4LS.png)
    - 當一個檔案正在使用時一次只能被一個應用程式使用時，因此當檔案被使用時，需將檔案上所防止他人使用。
    - 避免兩個檔案同時運作是發生問題
- `/var/log`：放置登入檔案的目錄
![](https://i.imgur.com/3MTau5G.png)
    - 非常重要，因此目錄紀錄了系統的重要訊息及錯誤訊息等，如果沒有紀錄的話可能會不知道有問題，也無法進一步解決問題
    - `/var/log/syslog`：紀錄系統登入資訊記錄及Kernel錯誤或警示資訊記錄等等
        - 設定檔案在`/etc/syslog.conf` or `/etc/rsyslog.conf`
    - `/var/log/boot.log` or `/var/log/bootstrap.log`：記錄系統開機或者服務啟動時，顯示的啟動或關閉訊息
    - `/var/log/mail.log`：紀錄郵件的往來資訊
    - `/var/log/wtmp` : 記錄登入者的相關資訊
    - `var/log/btmp` : 紀錄登入失敗的資訊
- `/var/mail`：放置個人郵箱信件的目錄
![](https://i.imgur.com/2q5AiaZ.png)

- `/var/spool`：放置佇列資料
    - 使用後的資料通常會被刪除
- `/proc` = process：放置系統中處理程序及執行緒的相關狀態資訊
![](https://hackmd.io/_uploads/H18QNB1r3.png)
    - 目錄本身是一個虛擬檔案系統(virtual filesystem)，目錄中放置的資料是在記憶體中，因此不佔硬體空間
    - 檔案可讀可寫
    - `/proc/cpuinfo`：紀錄 cpu 相關資訊
    ![](https://hackmd.io/_uploads/Bk8MNHyBh.png)
    - `/proc/interrupts`：紀錄系統中產生的中斷的詳細信息
    ![](https://hackmd.io/_uploads/HJt-NBkB3.png)
- `/lost+found`：如果系統檔案發生錯誤，會將遺漏的訊息放置到此目錄
    - 通常此目錄為空白的
- `/sys` = sysytem：與 `/proc` 相似，同樣為虛擬檔案系統，不佔硬體空間
![](https://hackmd.io/_uploads/BkYx4r1r3.png)
    - 與 `/proc` 不同的是，此目錄中通常只有一個值，可以直接讀取或寫入
    - `/sys/devices`：紀錄系統設備，並按照設備類型分類
![](https://hackmd.io/_uploads/ry1gVHJBh.png)
:::info
#### 小補充
- UNIX 系統
- BSD 系統
- 某些指令可能會因為系統版本的補同，而造成攔位不同
    - `top` 就像是系統中的工作管理員，可以監看目前所有程式的執行狀況。可以觀察程式運行所花的記憶體、CPU 還有各種其他資訊
    - `ps aux` :顯示 process
        - a ：不與 terminal 有關的所有 process
        - u ：有效使用者 (effective user) 相關的 process
        - x ：通常與 a 這個參數一起使用，可列出較完整資訊
:::

## 基本指令
- `cd` : change directory, 變換目錄
    - `cd <相對路徑 / 絕對路徑>`, `cd <特殊目錄>`
    - 特殊目錄
        - `.` : 現在這層目錄
        - `..` : 上一層目錄
        - `-` : 前一個工作目錄
        - `~` : 這個 user 的家目錄, `cd` 也可以直接回家目錄
        - `~user` : 指定 user 的家目錄
:::success
:bulb: 要善用 **tab**
:::
- `pwd` : print working directory, 現在在哪個路徑
    - 可加參數 `-P` ，會顯示連結到的實際路徑
- `ls` : list
   - 可加參數
     - `-a` : 全部檔案，包含開頭為 `.` 的隱藏檔案
     - `-A` : 包含隱藏的全部檔案，但不包含 `.` `..` 這兩個目錄
     - `-l` : 列出所有屬性與權限等等資料
     - - `<path>`
     ![](https://hackmd.io/_uploads/Bk3RQByS3.png)
   - 各欄位意義
     - 檔案類型
       ![](https://hackmd.io/_uploads/B11AQSyS3.png)
       - `-` : 一般檔案，白色字體；綠色為可執行檔案
       - `d` : 目錄，藍色字體
       - `l` : 連結檔案，淺藍色字體
       - `p` : 有用 `|` (pipe) 的檔案
       - `b` : 存取硬體設備的檔案 (暫存再寫入)，黃色字體
       - `c` : 存取硬體設備的檔案 (立即)，黃色字體
       - `s` : socket 檔案，粉紅色字體
     - 權限
       ![](https://hackmd.io/_uploads/H1Ea7HkSh.png)
       - 共三組 `rwx` , 分別代表 owner, group, other user 的權限
       - `r` : Read
       - `w` : Write
       - `x` : eXecute
     - 底下有幾個目錄 / Hard Link 數量
       ![](https://hackmd.io/_uploads/BJjnmrkrh.png)
     - 擁有者
       ![](https://hackmd.io/_uploads/rke3XSySh.png)
     - 群組
       ![](https://hackmd.io/_uploads/r1wimrJSn.png)
     - 檔案大小
       ![](https://hackmd.io/_uploads/Hk297ryBh.png)
     - 最後修改時間
       ![](https://hackmd.io/_uploads/BkXqmr1rn.png)

### 與檔案、目錄相關
- `touch <filename.filetpye>` : 建立空檔案
- `mkdir <directory name>` : 建立目錄
- `rmdir` : 刪除指定的**空**目錄
- `echo <content>` : 
    - `echo <content> > <filename>` : 建立一個檔案並把內容寫入，如果檔案已經存在**會清空**內容再寫入
    - `echo <content> >> <filename>` : 建立一個檔案並把內容寫入，如果檔案已經存在會 **append 在檔案的最後**
:::info
#### 在 bash 環境中的特殊符號
- `>` : 資料**輸出**導向，將輸出的資料覆蓋在指定檔案上
- `>>` : 資料**輸出**導向，將輸出的資料 append 在指定檔案
- `<` : 資料**輸入**導向
- `<<` : 資料**輸入**導向，指定結束的輸入字元
    - `cat > file << "eof"`
    - 輸入 `eof` 結束輸入，就不用 `ctrl+d` 結束鍵盤輸入
        - `ctrl+c` : 發出中斷訊號結束 process
        - `ctrl+z` : 暫停目前 process
        - `ctrl+l` : same as command `clear`
- `&` : 工作控制 (job control)，讓指令在背景工作
- `$` : 在變數前面要加的變數取代值
- `|` : pipe, 用於串接指令
    - `指令 | 指令`
    - e.g. 
      ![](https://hackmd.io/_uploads/rJlpfB1r3.png)
#### 輸入與輸出代碼
- `0` : 標準輸入，用 `<` 或 `<<`
- `1` : 標準輸出，用 `>` 或 `>>`
- `2` : 標準錯誤輸出，用 `2>` 或 `2>>`
#### 舉例 :chestnut:
- `ls > ls_file`
- `ls < /home/yaxuan`
- `ls > ls_file < /home/yaxuan`
    - `a > b < c` : 把 a 的輸出寫進 b，再把 c 當作 b 的輸入 
- `python hello.py > result.txt 2>&1` : 把正常輸出寫進檔案裡，且將錯誤輸出視為正常輸出
    - `hello.py > result.txt` : 把 hello.py 正常的輸出訊息覆寫進 resulte.txt 裡
    - `2>&1` : 把錯誤輸出視為正常輸出
- 為什麼要輸出錯誤訊息？
    - 如果使用者不是隨時都顧著伺服器，錯誤輸出很可能被忽略，所以才需要一個檔案紀錄。

#### PATH
- 在執行檔案的時候 e.g. `python hello.py` ，要在檔案的所在目錄底下才可以下這個指令，或是把檔案的**絕對路徑**打出來 `python /home/yaxuan/hello.py`
    - ![](https://hackmd.io/_uploads/SkGF7rJSn.png)
- 為什麼在下各種指令的時候只需要打指令本身，而不用把指令的絕對路徑打出來？ e.g. `ls` 
- 系統會從 PATH 這個環境變數底下的目錄搜尋距離現在目錄最近的該指令位置做執行
    - 指令的位置
        - `whereis <command>` : 在特定目錄下搜尋，下參數 `-l` 可以看搜尋路徑
        - `which <command>` : 列出從 PATH 找到的第一筆位址

    - `echo $PATH` : 顯示 PATH 這個 環境變數
    - `env` : environment, 顯示目前 shell 下的所有環境變數與說明
    - `export` : 除了顯示 `env` 的內容，可以修改環境變數
        - `export | grep PATH`
        - `export PATH="./home:$PATH"` : 前面新增變數
        - `export PATH="$PATH:/home"` : 後面增加變數
        - 更改的變數只在當下的 shell，如果要永久更動的話，要去修改 `.bashrc`
:::
- `cat` : concatenate, 檢視指定檔案的內容
    - `cat filename`
    - 可加參數
        - `-b` : 印出行號，空白行不標記
        - `-n` : 印出行號，空白行也標記行號
        - `-T` : 會把 TAB 按鍵用 ^I 顯示出來
- `rm <file / directories name>` : 刪除指定內容
    - `-r` : recursive, 會把目錄跟底下的檔案全部刪掉
    - `-f` : force
    - `rmdir <empty directory>`
- `mv` : 移動或更名
    - `mv <filename> <directory>`
    - `mv <filename> <filename_after_change>` 
- `cp` : copy
    - `cp <file> <copy_file>`
    - `cp <directory> <copy_dir>`
    -  可加參數 :
        - `-a` : 複製檔案全部特性
        - `-p` : 連同檔案的權限、owner、時間一起複製
    - 複製過程希望有進度條，可改用 `scp` 或 `rsync` 指令
- `grep <keywords>` : 從輸出中找指定的關鍵字 
    - `-i` : 列出所有不論關鍵字大、小寫的結果
    - `-E` : 用正規表示法顯示輸出

### 與連結相關
- `ln <destination> <link_name>` : 建立一個指到目標的連結
    - `ln <A> <B>` : Hard Link, `A` 跟 `B` 都知道檔案在哪裡
    - `ln -s <A> <B>` : Soft Link (Symbolic link),
      `B` 知道檔案在哪裡；
      `A` 不知道檔案在哪裡，但知道 ==`B` 知道檔案在哪裡==。


> - **Hardlink** 是幫檔案建立一個「別名」，但其實是同一個檔案。
        比如，蓬萊人偶就是柏瑋，柏瑋就是蓬萊人偶。只是有兩個名字。 
> - **Symlink** （softlink）是一個獨立檔案，是一種特殊檔案。
        他的內容是儲存一個「路徑」。
        比如，路牌指向學校大門。路牌是路牌，只是表示出大門的位置是哪裡。
> [name=BT]

### 與使用者相關
- `sudo <指令>` : super user do, 輸入使用者的密碼用 root 的身分執行指令
    - 可以執行的指令被記錄在 `/etc/sudoers` , root 用 visudo 才能編輯該檔案
      ![](https://hackmd.io/_uploads/B1Nd7Byr3.png)
- `su`: 輸入 root 的密碼改變身分
    - 不建議用 `su` 登入 root 管理主機, 因為需要知道 root 的密碼，如果密碼外流會不安全
    - 用 `sudo` 就好 
- `whoami` : 現在是哪個使用者
- `sudo adduser <new_user_name>` : 創建使用者與他的家目錄
- `sudo deluser <username>` : 刪除使用者
- `sudo su - <user_name>` : 切換使用者
- `exit` : 登出現在的使用者
- `last` : 列出使用者登入的資訊
    - `/var/log/wtmp` 內容編碼過，用 `last` 指令查詢
    - `last -5`, `last -n 5` : 列出前 5 行的資訊，依參數中的數字列出
- `id` : 查看自己的 UID, 所屬群組的 GID
    - `sudo id <others_username>` : root 查閱其他使用者 UID, GID
    - 系統如何辨別使用者？ 看 ID
    - 所以如果把自己的 UID 改成 test 的 UID，自己原本 owner 的檔案權限會消失，系統會視為是 test 的，也因為 UID 相同，可以到別人的家目錄新增檔案。
        - UID 放在 `/etc/passwd` 第三個欄位
        - 0 是 root
          1~500 是 系統保留的 ID
          500~65535 是一般使用者，依序遞增
        - 家目錄的權限
          ![](https://hackmd.io/_uploads/HyiwXHJr2.png)
          > owner : rwx
          > group : r-x
          > others : r-x, 可讀取也可 cd 進該目錄，但不能編輯、新增、刪除此目錄

- `passwd` : 修改密碼
    - 一般使用者直接下 `passwd` 即可
    - root 可 `passwd <username>` 
- `finger` : 查詢使用者的相關訊息
    - `finger <username>`
- `usermod` : 修改使用者資訊
    - `sudo usermod -l <new_name> <old_name>` ： 修改帳號名稱， 
    - `sudo usermod -s <shell dir> <username>` ：修改使用者登入的起始位置
    - `sudo usermod -a -G <group_name> <user_name>` : 新增群組
        - `-G` ： 接次要群組，修改這個使用者能夠支援的群組
        - `-a` ： 與 `-G` 合用，可『增加次要群組的支援』而非『設定』
- `groups` : 顯示出目前的使用者的所屬群組
- `groupadd` : 新增群組
    - `sudo groupadd <group_name>`
    - 可加參數 `-g <num>` : 自訂 GID
    - 也可直接編輯 `/etc/group` 與 `/etc/gshadow` 這兩個檔案 

- `groupmod` : 修改與 group 相關資訊
    - `groupmod [-g gid] [-n new_name] <group_name>`
    - `-g` : 修改現有群組的 GID, 建議不要隨意更動
    - `-n` : 修改現有群組的群組名稱
- `groupdel` : 刪除群組
    - `sudo groupdel <group_name>`
    - 沒有使用者把要刪除的群組當作 initial group 的狀況下才能夠刪除群組
        - 查看 `/etc/passwd` 第四個欄位
- `gpasswd` : 群組管理相關指令
    - 系統管理員 root 可執行的指令
        - `gpasswd <groupname>` : 沒有給參數，設定群組密碼
        - `-A <username>` : 新增 user 成為群組管理員
        - `-M <username>` : 新增 user 進群組
        - `-r` : 刪除該群組的密碼
        - `-R` : 讓該群組的密碼欄失效
    - 群組管理員可執行的指令
        - `gpasswd -a <username> <group_name>` : 將指定 user 新增至群組
        - `gpasswd -d <username> <group_name>`: 將指定 user 從群組移除
- ![](https://hackmd.io/_uploads/Sy1DXSJHh.png)


### 與權限相關
- `chmod` : 改變使用者權限
    - `chmod 755 <filename/dir_name>` : owner 可讀可寫可執行，其他使用者可讀可執行
    ![](https://hackmd.io/_uploads/rJLUmHyr3.png)
    - 權限之於檔案
        - r : 可讀取**檔案內容**
        - w : 可編輯**檔案內容**，但沒有刪除檔案的權限
        - x : 可以把**檔案內容**丟給系統執行
    - 權限之於目錄
        - 目錄是一張記錄檔案名稱的清單
        - r : 可讀取這張清單
        - w : 可編輯這張清單，等同可以編輯名稱、新增、刪除、移動該目錄底下的檔案或目錄
        - x : 可以 `cd` 進目錄
            - 所以要開放目錄給大家看的話，至少要給 `r-x` 的權限
- `chgrp` : change group, 改變所屬群組
    - `chgrp [-r] <group name> <dirname/filename>`
      - `-r` : recursive, 進行遞迴的持續變更，常用在目錄變動的參數
    - `/etc/group` 中記錄現有的群組，群組名稱要在檔案裡才可以執行 `chgrp` 指令
      ![](https://hackmd.io/_uploads/BkNtlSJrn.png)

      > 由左而右的 4 個欄位內容
      > 1. 群組名稱
      > 2. **群組密碼** : 因為很少用到群組登入，所以通常不會設定群組密碼，==真正的群組密碼被記錄在 `/etc/gshadow` 裡面==
      > 3. Group ID (GID)
      > 4. **在群組內的 user** : 如果想調整群組內 user 可直接編輯檔案，但 user 之間不要加空格
>F 

- `chown` : change owner, 改變檔案 / 目錄擁有者
    - `/etc/passwd` 中記錄現有的使用者，使用者要被記錄在檔案裡才可以執行 `chown` 指令
    - `chown [-R] <user_name> <dirname/filename>`
    - `chown [-R] :<group_name> <dirname/filename>`
    - `chown [-R] <user_name>:<group_name> <dirname/filename>`
        - `-R` : recursive, 可以連同目錄底下的檔案一起變更使用者

### 與查詢相關
- `man <指令>`, `<指令> -h`, `<指令> --help` : 查使用方式
- `less` : 
    - `/keywords`
- `whereis <欲尋找位置的檔案/目錄>` : 由一些特定的目錄中尋找檔案檔名
    - `-l` : 可以列出 whereis 會去查詢的幾個主要目錄而已
    - `-b` : 只找 binary 格式的檔案
    - `-m` : 只找在說明檔 manual 路徑下的檔案
    - `-s` : 只找 source 來源檔案
    - `-u` : 搜尋不在上述三個項目當中的其他特殊檔案

- `which <欲尋找的執行檔>` : 列出第一筆由 PATH 目錄中找到的結果
    - `-a` : 將所有找到的指令均列出
    - `echo $PATH`
        - PATH : 由一堆目錄所組成的[]
- `env` : environment, 列出現在的 shell 環境 ( Linux 預設 `/bin/bash`) 下的所有環境變數跟內容
- `type <指令名稱>` : 查詢指令是否為 Bash shell 的內建命令，output 會顯示外部指令或 bash 內建指令
    - `-t` : 以底下的字顯示出指令意義
        - file    ：表示為外部指令
        - alias   ：表示該指令為命令別名所設定的名稱
        - builtin ：表示該指令為 bash 內建的指令功能, e.g. `cd`


### 與下載相關
- `apt install <packagename>` : 從 APT 平台中的 package 安裝，會放在 /usr/local
    - `apt remove <packagename>`
    - `apt list`
    - `sudo apt install sl`
- `wget <網址>` : 從指定網址安裝，會放在 /opt
- `dpkg -i <filename.deb>` : 用 deb 檔型安裝，會放在 /opt
    - `-i` : install
    - `-r` : remove
    - `-l` : list

### 與網路相關
- `ifconfig` : 查看目前已啟動網卡的相關資訊
    - 安裝 : `sudo apt install net-tools`
    - 執行
      ![](https://hackmd.io/_uploads/rkYqxryH3.png)
      > enp0s3 : 網卡代號
          > `ifconfig <網卡代號>` : 顯示指定網卡的資訊
      > inet : IPv4 的 IP 位址
    - `sudo ifconfig <網卡名稱> down` : 關閉網卡
    - `sudo ifconfig <網卡名稱> up` : 開啟網卡
    - `ifconfig -a` : 查看所有網卡
- `route` : 看自己的 routing table
    - `-n` : 會把能變成數字的資訊變成數字，主機名稱以 IP 顯示
- `iproute2` : 網路參數綜合指令，可以取代 ifconfig route
    - `ip [option] [動作] [指令]`
        - option : 可設定的參數, 以 `-s` 為主
            - `-s` ： 顯示出該裝置的統計數據(statistics)，例如總接受封包數等
        - 動作：可以針對哪些網路參數進行動作
            - `link` : 關於裝置 (device) 的相關設定，包括 MTU, MAC 位址等等
            - `addr/address` ： 關於額外的 IP 協定，例如多 IP 的達成等等
            - `route` ： 與路由有關的相關設定
        - 指令
            - `show` : 查閱
            - `set` : 設定
    - `ip [-s] link [指令]`
        - `show` : 查閱
            - `ip [-s] link show` : 查閱所有網卡資訊
            - `ip [-s] link show <網卡卡號>` : 查閱指定網卡資訊
        - `set` : 設定
            - `ip [-s] link set <網卡卡號> up` : 開啟網卡
            - `ip [-s] link set <網卡卡號> down` : 關閉網卡
            - 其他: address 設定網卡位址, name 設定網卡名稱, mtu 設定網卡最大的傳輸單元
    - `ip [-s] addr [指令]`
        - `show` : 查閱
            - `ip addr/address show` : 查閱 IP 參數
        - `add / del` : IP 參數增加或刪除
            - `ip address [add|del] [IP參數] [dev 裝置名] [相關參數]`
    - `ip [-s] route [指令]`
        - `show` : 查閱
            - `ip route show/list` : 查閱 routing table
        - `add / del` : 增加或刪除 route
            - `ip route [add|del] [IP或網域] [via gateway] [dev 裝置]`
- `netstat` : 可以看到目前電腦網路的詳細狀況
    - `netstat -rn`
        - `-r` : 列出 routing table ，功能同 `route` 指令
        - `-n` : 會把能變成數字的資訊變成數字，主機名稱以 IP 顯示
    - `sudo netstat -ntupl` : 可以看到目前電腦網路的詳細狀況，檢查各服務的 port 號等
        - `-t` : 顯示 tcp
        - `-u` : 顯示 udp
        - `-p` : 列出 PID 與 Program 的檔名
        - `-l` : 目前監聽到的
- `ss` : Socket Statistics, 顯示 Sockets 的統計資訊, 跟 netstat 指令類似, 但因從 kernel 讀取數據, 所以速度較快
    - `-l` : 列出全部開啟的埠號
    - `-pl` : 列出開啟 Socket 的 process 名稱
    - `-a` : 列出所有資訊
    - `-t` : 只列出 TCP Sockets
    - `-u` : 只列出 UDP Sockets
    - `-x` : 只列出 Unix Sockets
    - `-4` : 只列出 IPv4 Sockets
    - `-6` : 只列出 IPv6 Sockets
- `ps -aux` : 列出執行中的 process
    - 參數
        - `-A` ：所有的 process 都列出，與 `-e` 具有同樣的效用
        - `-a` ：不與 terminal 有關的所有 process
        - `-u` ：有效使用者 (effective user) 相關的 process
        - `x` ：通常與 `a` 這個參數一起使用，可列出較完整資訊
    - USER : process 擁有者
    - PID : process id
    - %CPU : 佔用 CPU 的使用率
    - %MEM : 佔用實體記憶體的比例
    - VSZ : 佔用的虛擬記憶體大小
    - RSS : 佔用的記憶體大小



<!-- 
## 實作
### 火車快飛
在主機新建一個使用者 `train`，登入此使用者之後會直接自動執行印出火車的命令 (sl)，執行結束後，就直接登出
```shell=
sudo adduser train 
sudo apt install sl
which sl
sudo vim /etc/passwd     /* train 的 /bin/bash 改成 /usr/games/sl */
sudo su - train
```

### web server
- `sudo apt install nginx`
- `sudo service nginx staus`
- search 127.0.0.1
- `sudo netstat -ntupl`
- 停用服務 `sudo service nginx **stop**`
- `cd /etc/nginx`
- `sites-available`
  `sites-enabled` : 服務啟動時會用到的檔案
- `sudo cp -a /etc/nginx/sites-available/default /etc/nginx/sites-available/default.backup`
- `sudo ln -s /etc/nginx/sites-available/default /etc/nginx/sites-enabled/`
- 更改 default
    - listen 8080 default_server：改聽 8080 port
- `netstat -ntupl`

---
 -->