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)。

萬用字元與特殊符號#

符號意義
*匹配零個或多個字元
?匹配恰好一個字元
[]匹配括號中的任一字元
#註解
\跳脫字元
$取用變數
&背景執行