# 命令列與 Shell 腳本導論

> 💡 **學習指南**：本章節旨在為零基礎讀者提供一個關於終端機（Terminal）運作原理的系統性認知。無需具備電腦專業背景，我們將透過互動式演示，由淺入深地解析終端機的運行機制。

## 0. 快速上手：打開終端機的方法

在你開始學習之前，首先得找到它。終端機是每個作業系統的「出廠標配」，你不需要安裝任何軟體就能使用它。

::: info 🖥️ 不同系統的開啟方式

** macOS (Mac)**

1. 按下 `Command (⌘) + Space` 開啟 Spotlight 搜尋。
2. 輸入 `Terminal` 或「終端機」。
3. 按下 Enter 鍵，你就會看到一個白底黑字（或黑底白字）的視窗。

**🪟 Windows**

- **方法一 (CMD)**：按下 `Win + R`，輸入 `cmd`，按 Enter。這是最古老的命令列。
- **方法二 (PowerShell)**：按下 `Win + R`，輸入 `powershell`，按 Enter。這是更現代、功能更強大的終端機。
- _建議：日常簡單操作兩者皆可，開發環境推薦使用 PowerShell 或安裝 WSL (Windows Subsystem for Linux)。_

**🐧 Linux**

- 通常快捷鍵是 `Ctrl + Alt + T`。
- 或者在應用程式選單中搜尋 `Terminal`。

:::

### 0.1 實作演練：先玩玩看

光說不練假把式。在了解枯燥的原理之前，我們先親手體驗一下「敲指令」的感覺。

> 💡 **提示**：為了安全和方便，推薦你在下方的**網頁模擬器**中操作。如果你有信心，也可以按照第 0 章的方法打開你電腦上真實的終端機，跟隨步驟一起練習（效果是一樣的）。

在這個練習中，你將學會：

1. **檢視檔案**：學會用 `ls` 或 `dir` 看看目前目錄下有什麼。
2. **建立與進入**：學會用 `mkdir` 建立新資料夾，用 `cd` 像傳送門一樣進入它。
3. **新增檔案**：學會用指令快速建立一個新檔案。
4. **安裝軟體**：體驗一行程式碼安裝 Python 函式庫或系統軟體的快感。
5. **刪除清理**：學會如何刪除不需要的檔案（慎用！）。
6. **求助 AI**：這是最重要的！當你忘記指令時，學會問 AI：「在 Mac 上怎麼刪除檔案？」，它會直接告訴你答案。

_請在下方選擇你常用的作業系統，然後跟隨引導開始操作：_

<TerminalHandsOn />

### 0.2 要放棄滑鼠的動機

你可能會問：_「現在的圖形介面（GUI）這麼好用，滑鼠點點就好，為什麼還要對著黑底白字的視窗敲複雜的指令？」_

這並非為了「裝極客」，而是因為在特定場景下，**語言（指令）比手勢（滑鼠）更強大**。

#### 1. 滑鼠難以表達「批次」與「邏輯」

- **GUI（滑鼠）**：適合「看到什麼點什麼」。如果你想刪除一張照片，右鍵刪除很快。但如果你想「刪除所有 2023 年拍攝的、大小超過 5MB 的、格式為 PNG 的照片」，滑鼠就無能為力了，你可能需要手動篩選半天。
- **CLI（指令）**：適合「描述你想做什麼」。上述需求只需要一行指令，電腦會自動幫你找出符合條件的檔案並處理，哪怕有 10000 張。

#### 2. 指令可以被記錄和重複使用

- **GUI**：你設定一次環境，需要點擊幾十次選單。下次換台電腦，你還得憑記憶重新點一遍，很容易漏掉步驟。
- **CLI**：你可以把所有指令寫進一個檔案（腳本）。下次只需要執行這個檔案，電腦會**零誤差**地重現你的操作。這就是「自動化」的基礎。

#### 3. 遠端控制的唯一選擇

- **GUI**：傳輸畫面就像看高畫質影片，需要極高的網速。如果網路稍微卡一點，滑鼠就會卡頓，根本沒法操作。
- **CLI**：傳輸的只是純文字，幾十個字元。哪怕你在訊號極差的山區，也能順暢地控制遠在地球另一端的資料中心伺服器。

**總結**：GUI 適合**探索**（瀏覽網頁、看圖），CLI 適合**生產**（開發、維運、批次處理）。作為開發者，我們使用終端機是因為它**更精確、更可控、更高效**。

## 1. 概念界定：終端機概述

_不同作業系統下的終端機長相不同，**指令方式也不同**。點擊下方按鈕切換檢視，注意觀察 macOS、Windows 和 Linux 是如何用不同的指令（如 `dir` vs `ls`）做同一件事的：_

<TerminalOSDemo />

在圖形使用者介面（GUI）普及之前，終端機是人類與電腦互動的主要方式。即便在今天，它依然是開發者控制電腦最精確、最高效的工具。

<TerminalDefinition />

本質上，終端機是一個**字元流輸入/輸出環境**：

- **輸入**：透過鍵盤傳送指令（字元訊號）。
- **輸出**：透過螢幕網格顯示文字回饋。

它不處理複雜的圖形、圖片或影片，而是專注於**文字資訊的互動**。

## 2. 核心架構：解耦的藝術

在深入了解之前，請先思考一個問題：**終端機視窗自己真的懂你在說什麼嗎？**

其實，終端機（Terminal）就像是一個**只會傳話的顯示器**。當你輸入 `date` 指令時，終端機並不知道這是「檢視日期」的意思，它只是把這 4 個字母打包發給了幕後的真正大佬——**Shell**。

Shell 才是那個能聽懂你說話、並指揮電腦幹活的「大腦」。

為了搞清楚它們是如何配合的，我們來看這三個分工明確的「打工人」。要理解它們的關係，最好的比喻是**瀏覽器**與**網站伺服器**。

### 2.1 角色分工

- **🖥️ 終端機 (Terminal) —— 就像「瀏覽器」**
  - **職責**：它只負責**輸入**（把你的按鍵告訴對方）和**顯示**（把對方傳回來的字元畫在螢幕上）。
  - **特點**：它本身**沒有任何智慧**，也不懂什麼叫 `ls` 或 `cd`。它就像 Chrome 瀏覽器，不管你造訪的是百度還是 Google，它只管渲染網頁。
  - _常見的終端機_：Windows 的 CMD/PowerShell 視窗，macOS 的 Terminal.app，VS Code 內建的終端機。

- **🧠 Shell (殼) —— 就像「網站伺服器」**
  - **職責**：它才是有邏輯的大腦。它在背景執行，負責**接收**你發來的指令字串，**解析**它的含意，然後**指揮**作業系統執行。
  - **特點**：它看不見摸不著，只能透過文字流與外界交流。
  - _常見的 Shell_：Bash、Zsh、Fish、PowerShell。

- **⚙️ 核心 (Kernel) —— 幕後的「大管家」**
  - **職責**：作業系統的核心，只有它能直接控制硬體（讀寫硬碟、分配記憶體、控制 CPU）。
  - **關係**：Shell 是核心的「秘書」，幫你把人話翻譯給核心聽。

### 2.2 分開的動機（可替換性）

正因為**顯示層**（終端機）和**邏輯層**（Shell）是完全分開的，所以它們可以自由搭配：

- **換個「外觀」**：你可以在 macOS 上用內建的終端機，也可以下載 iTerm2，或者用 VS Code 的終端機。它們長相不同，但連的都是同一個 Shell (zsh)，所以指令一模一樣。
- **換個「大腦」**：你可以在同一個終端機視窗裡，從 bash 切換到 zsh，或者切換到 Python 互動環境。這時，終端機沒變，但處理指令的邏輯變了。

### 2.3 互動流程：消失的按鍵

你可能認為：_「我在鍵盤上按個 'a'，終端機就在螢幕上畫個 'a'。」_
**錯！** 真實的流程是這樣的（這叫**回顯 Echo**）：

1. **按下 'a'**：鍵盤訊號傳給終端機。
2. **發送訊號**：終端機把 'a' 的編碼發給 Shell。
3. **Shell 處理**：Shell 收到 'a'，覺得沒問題，於是原樣把 'a' 發回給終端機。
4. **顯示字元**：終端機收到 Shell 發回來的 'a'，這才把它畫在螢幕上。

> 💡 **小實驗**：有些指令（如輸入密碼時）會關閉 Shell 的回顯功能。這時你按鍵盤，終端機發給了 Shell，但 Shell **不發回**任何東西，所以螢幕上一片空白。這就是為了保護隱私。

**一句話總結流程**：
你在終端機打字 ➡️ 訊號傳給 Shell ➡️ Shell 原樣發回（你看到了字）並理解 ➡️ Shell 指揮核心幹活。

_下方的演示展示了這個過程，注意看 Shell 和核心之間那道「牆」，以及字元是如何一來一回的：_

<ArchitectureDemo />

## 3. 視覺模型：網格系統

與現代圖形介面使用「像素」不同，終端機的顯示基礎是**字元網格（Character Grid）**。
終端機螢幕被劃分為若干行和列，每一個格子稱為一個**單元格（Cell）**。

### 3.1 單元格的構成

每個單元格是終端機顯示的最小單位，它包含兩類核心資訊：

1. **字元 (Glyph)**：實際顯示的文字（如 `A`、`中`、`$`）。
2. **屬性 (Attributes)**：字元的樣式（如前景色、背景色、粗體、底線）。

當你拖動終端機視窗改變大小時，本質上是在改變這個網格的**行數 (Rows)** 和 **列數 (Columns)**。

_請在下方互動區域嘗試操作，觀察網格如何承載字元：_

<TerminalGrid />

### 3.2 樣式檢查

終端機無法顯示圖片，所有的「介面」都是透過字元顏色和樣式的組合來實現的。

_點擊下方單元格，查看每個格子背後包含的樣式屬性：_

<CellInspector />

## 4. 通訊協定：跳脫序列

你可能會疑惑：既然終端機只傳輸文字，那彩色的文字、移動的游標、清螢幕操作是如何實現的？

答案是**跳脫序列（Escape Sequences）**。
這是一串特殊的字元指令（通常以 `ESC` 字元開頭）。當終端機接收到這些字元時，**不會將它們顯示在螢幕上**，而是將其解讀為**控制指令**。

例如：

- 普通字元 `A` → 在螢幕上畫出 A。
- 序列 `\033[31m` → **指令**：將後續文字顏色設為紅色。
- 序列 `\033[2J` → **指令**：清空螢幕。

這就好比你和朋友約定：如果我正常說話，你就記錄下來；如果我舉起左手（相當於 `ESC`），接下來的那句話就是指令而不是內容。

_點擊下方的「播放」按鈕，觀察終端機是如何逐個處理字元流，並識別出隱藏的指令：_

<EscapeParserDemo />

_下方元件則展示了更多種類的跳脫序列及其渲染效果：_

<EscapeSequences />

## 5. 輸入機制：位元組流

輸入過程往往被誤解。當你按下鍵盤時，終端機並沒有直接把字元「畫」在螢幕上，而是進行了一次**編碼傳輸**。

1. **按鍵捕獲**：終端機捕獲你的實體按鍵動作。
2. **編碼轉換**：將按鍵轉換為特定的**位元組序列**。
   - 按下 `a` → 發送位元組 `a`。
   - 按下 `向上鍵` → 發送序列 `^[[A`。
3. **發送**：將位元組流發送給 Shell 或目前正在執行的程式。

**關鍵點**：所有的按鍵（包括功能鍵、滑鼠點擊）在傳輸層面上都是**位元組資料**。

_在下方嘗試按鍵，觀察你的輸入是如何被轉換為底層資料的：_

<InputVisualizer />

## 6. 運行模式：打字機 vs 遊戲機

終端機有兩種截然不同的性格。理解這一點，你就能明白為什麼在終端機裡**打指令**和**玩貪食蛇**是完全不同的體驗。

- **加工模式 (Cooked Mode) —— 像打字機**
  - 這是預設模式。
  - **行為**：你輸入的字元會被終端機**暫時扣留**，直到你按下 Enter 鍵。
  - **好處**：這給了你修改的機會。打錯了？按退格鍵（Backspace）刪掉重寫，程式根本不知道你之前打錯過。
  - _適用場景：平時敲指令（如 `ls`、`cd`）。_

- **原始模式 (Raw Mode) —— 像遊戲手把**
  - 這是「高手」模式。
  - **行為**：你按下的每一個鍵（包括方向鍵、Ctrl 組合鍵），都會**瞬間**發送給程式，沒有任何緩衝。
  - **好處**：程式能即時回應你的操作。
  - _適用場景：玩終端機遊戲（如貪食蛇）、使用 Vim 編輯器（一種純鍵盤操作的編輯器）。_

_點擊下方按鈕切換模式，體驗「寫信」與「打遊戲」的不同手感：_

<CookedRawDemo />

## 7. 行程控制：訊號 (Signals)

在終端機中按下 `Ctrl+C` 通常能停止程式。這並非透過發送字元實現，而是觸發了**訊號（Signal）**。

訊號是作業系統層級的通知機制，用於告訴程式發生了特定事件。

- **Ctrl+C** → 發送 `SIGINT` (Interrupt)：通知程式「請中斷目前操作」。
- **Ctrl+Z** → 發送 `SIGTSTP` (Suspend)：通知程式「請暫停並掛起到背景」。

這一機制繞過了標準的資料輸入通道，確保在程式當機時使用者仍有控制權。

<SignalsDemo />

## 8. 進階應用：全螢幕介面與緩衝區

你有沒有發現，當你用 `vim` 編輯檔案或者用 `htop` 看系統狀態時，它們會佔滿整個螢幕？而當你退出它們時，螢幕瞬間變回了原來的樣子，之前的指令記錄完全沒變。

這是因為終端機有兩塊「畫布」在來回切換：

- **主緩衝區 (Primary Buffer)**：就像**草稿本**。
  - 你寫一行，系統回一行。
  - 寫滿了就翻頁（捲動），以前寫的東西都在上面。
  - _用於：日常敲指令。_

- **備用緩衝區 (Alternate Buffer)**：就像**黑板**。
  - 程式把黑板擦乾淨，在上面畫畫（全螢幕顯示）。
  - 不管怎麼畫，都不會影響你桌子上的草稿本。
  - 當你退出程式時，就像把黑板收起來，你又回到了草稿本面前。
  - _用於：Vim、Nano、遊戲等全螢幕軟體。_

_點擊下方按鈕，體驗「草稿本」和「黑板」是如何瞬間切換的：_

<BufferSwitchDemo />

---

## 9. 總結

終端機並非神秘的黑盒子，它是一個標準化的文字互動介面。

- **顯示**：基於網格和字元。
- **控制**：基於跳脫序列。
- **互動**：基於輸入輸出流和訊號。

透過理解這些底層原理，你不再只是死記硬背指令，而是能真正理解每一次敲擊鍵盤背後發生的邏輯流轉。

## 附錄：常用術語表

| 術語 | 英文 | 解釋 |
| :--- | :--- | :--- |
| **終端機** | Terminal | 負責顯示和輸入的視窗程式（前端）。 |
| **Shell** | Shell | 負責解析指令和執行邏輯的程式（後端）。 |
| **CLI** | Command Line Interface | 命令列介面，一種基於文字的互動方式。 |
| **TUI** | Text User Interface | 文字使用者介面，指在終端機中透過字元建構的偽圖形介面。 |
| **跳脫序列** | Escape Sequence | 用於控制終端機游標、顏色等的特殊字元指令。 |
| **標準輸入/輸出** | Stdin/Stdout | 程式接收資料和輸出資料的標準通道。 |

## 參考資料

- [How Terminals Work](https://how-terminals-work.vercel.app/)：本文的結構與演示靈感深受該專案的啟發。如果你希望深入了解工程實作細節，強烈推薦閱讀原版教學。
