Shell 的角色:使用者與核心之間的翻譯官#
**核心(Kernel)**直接管理硬體,但使用者無法直接與核心溝通。Shell 就是那個中介層——它接收使用者輸入的文字指令,翻譯成核心能理解的系統呼叫,再將結果回傳給使用者。
Linux 支援多種 Shell(sh、bash、csh、zsh 等),系統合法可用的 Shell 列在 /etc/shells 中。**Bash(Bourne Again Shell)**是目前最廣泛使用的 Shell,也是大多數 Linux 發行版的預設 Shell。
Bash 的核心特性#
- 命令歷史(history):記錄執行過的指令,可用上下鍵瀏覽或搜尋
- Tab 補全:自動補全指令、檔名、路徑
- 命令別名(alias):為常用的長指令建立簡短別名
- 工作控制(Job Control):管理前景與背景程式
- 萬用字元(Globbing):
*、?、[]等,用於批次匹配檔案名稱
變數:Shell 操作的核心機制#
變數是 Bash 中最重要的概念之一。它的本質是用一個名稱代替一段可變動的資料。
環境變數 vs. 自訂變數#
- 環境變數:會被子程序繼承。用
export將自訂變數提升為環境變數 - 自訂變數:只存在於目前的 Shell 程序中,不會傳遞給子程序
這個區別在實務中非常關鍵。當你在 Shell 中設定了一個變數,然後執行一個 script(它會在子程序中執行),script 讀不到這個變數——除非你用
export匯出它。這是許多「環境變數設定了但沒生效」問題的根因。
重要的環境變數#
| 變數 | 用途 |
|---|---|
PATH | 指令搜尋路徑 |
HOME | 使用者家目錄 |
SHELL | 目前使用的 Shell |
LANG | 語系設定 |
PS1 | 命令提示字元的格式 |
? | 上一個指令的回傳值(0 = 成功) |
變數設定規則#
- 等號兩邊不能有空格:
name=value(正確)、name = value(錯誤) - 值中有空格要用引號包裹
- 雙引號會解析變數:
"Hello $USER" - 單引號不會解析:
'Hello $USER'就是字面意思 - 反引號或
$()用於指令替換:將指令的輸出作為變數值
語系(Locale)#
語系設定影響:
- 文字的排序順序
- 日期時間的格式
- 正規表示法中字元集的範圍
語系設定會影響正規表示法的行為。例如
[a-z]在不同語系下匹配的字元範圍不同。在寫 script 時,如果需要精確的字元匹配,建議明確設定LANG=C。
資料流重導向#
這是 Shell 最強大的概念之一。Linux 的每個程序啟動時都有三個預設的資料流:
- 標準輸入(stdin):編號 0,預設來自鍵盤
- 標準輸出(stdout):編號 1,預設導向螢幕
- 標準錯誤(stderr):編號 2,預設導向螢幕
重導向的核心思想是改變這些資料流的方向:
>/>>:將 stdout 導向檔案(覆蓋 / 追加)2>/2>>:將 stderr 導向檔案<:將檔案作為 stdin<<:Here Document,在指令中直接提供多行輸入/dev/null:黑洞裝置,丟棄所有導向它的資料
將 stdout 和 stderr 分開處理是 Shell 操作的精髓。例如,你想看指令的正常輸出但忽略錯誤訊息:
command 2>/dev/null。或者你想把錯誤訊息另存一份來分析:command > output.log 2> error.log。
指令的連續執行#
;:無條件依序執行&&:前一個成功才執行下一個||:前一個失敗才執行下一個
$?是判斷指令是否成功的關鍵——回傳值 0 代表成功,非 0 代表失敗。&&和||就是根據$?來決定是否執行下一個指令。
管線命令(Pipe)#
管線 | 將前一個指令的 stdout 導向下一個指令的 stdin,讓多個簡單的指令組合成強大的資料處理鏈。
管線只處理 stdout,不處理 stderr。如果你需要在管線中一併處理錯誤訊息,需要先用
2>&1將 stderr 合併到 stdout。
常見的管線工具#
- 擷取:
cut(欄位切割)、grep(模式搜尋) - 排序與統計:
sort(排序)、uniq(去除重複)、wc(字數/行數統計) - 雙向輸出:
tee(同時輸出到螢幕和檔案) - 字元轉換:
tr(字元替換/刪除) - 參數代換:
xargs(將 stdin 轉換為指令參數)
管線的哲學是 Unix 的核心設計原則之一:每個工具做好一件事,然後透過管線組合。這個原則在現代軟體設計中依然適用——微服務架構就是類似的思想。
Shell 的環境設定#
Login Shell vs. Non-login Shell#
- Login Shell:需要輸入帳號密碼登入時啟動。會讀取
/etc/profile→~/.bash_profile - Non-login Shell:已登入後開啟的新 Shell(如在圖形介面開啟終端)。只讀取
~/.bashrc
這就是為什麼有時候設定了環境變數卻「沒生效」——你可能把它寫在了錯誤的設定檔中。一般建議將自訂環境放在
~/.bashrc,因為它在兩種情境下都會被讀取(~/.bash_profile通常會 source~/.bashrc)。
萬用字元與特殊符號#
| 符號 | 意義 |
|---|---|
* | 匹配零個或多個字元 |
? | 匹配恰好一個字元 |
[] | 匹配括號中的任一字元 |
# | 註解 |
\ | 跳脫字元 |
$ | 取用變數 |
& | 背景執行 |