Shell 是作業系統核心與用戶/應用程式之間的命令解釋器介面,同時也是一門程式設計語言。它接收用戶輸入 (交互式) 或讀取腳本文件 (非交互式),解析後調用核心系統調用執行。掌握 Shell 是 Linux/Unix 系統管理、自動化運維、DevOps、資料處理的基石技能。
| 模式 | 特徵 | 典型場景 | 啟動文件 |
|---|---|---|---|
| 交互式 登入 Shell | 用戶登入終端 (SSH/Console/GUI Terminal),等待輸入,有提示符 (PS1) | 日常管理、除錯、臨時命令 | /etc/profile → ~/.bash_profile / ~/.profile / ~/.zprofile |
| 交互式 非登入 Shell | 在終端內輸入 bash/zsh 開啟子 Shell,或打開新分頁/終端視窗 | 臨時測試、嵌套操作 | ~/.bashrc / ~/.zshrc |
| 非交互式 Shell | 執行腳本 ./script.sh、bash script.sh、ssh host 'cmd'、Cron 任務、CI/CD Pipeline | 自動化腳本、批次處理、系統啟動腳本 | 環境變數 BASH_ENV / ENV 指定文件 (無預設) |
| 家族 | 代表成員 | 特點 | 預設登入 Shell | 推薦場景 |
|---|---|---|---|---|
| Bourne 系 (sh 兼容) | bash (Bourne Again SHell) | GNU 專案、POSIX 兼容、功能最豐富、生態最完善、幾乎所有 Linux 預設 | RHEL/CentOS/Fedora/Debian/Ubuntu/Arch/Kali 等絕大多數發行版 | 通用腳本、系統管理、CI/CD、最大兼容性需求 |
| dash (Debian Almquist SHell) | 極輕量、啟動極快、嚴格 POSIX、無交互功能 | Debian/Ubuntu 系統 /bin/sh 指向 dash | 系統啟動腳本、嵌入式、極致效能要求 | |
| ash / busybox ash | 極簡、BusyBox 核心組件、路由器/容器/嵌入式標配 | Alpine Linux / OpenWrt / Docker 基礎映像 / 嵌入式設備 | 容器入口腳本、極小體積環境 | |
| C Shell 系 | csh (C SHell) | C 風格語法、作業控制、歷史機制、別名、但腳本編程極不推薦 (語法缺陷、不可移植) | 早期 BSD、舊版 macOS (預設 tcsh) | 僅交互使用,嚴禁寫腳本 |
| tcsh (TENEX C Shell) | csh 增強:命令行編輯、檔名補全、拼寫修正 | FreeBSD 預設 / 部分舊系統 | 交互舒適,腳本同禁用 | |
| 新世代 | zsh (Z Shell) | bash 兼容 + 強大補全/提示/主題/插件生態 (Oh My Zsh / Powerlevel10k)、語法高亮、歷史共享 | macOS Catalina+ / Kali 2020+ / 眾多開發者首選 | 日常交互首選、腳本兼容 bash、插件生態豐富 |
| fish (Friendly Interactive SHell) | 開箱即用、語法簡潔、自動建議、Web 配色、無需配置 | 部分發行版可選、手動安裝 | 新手友好、交互體驗極佳、腳本語法不兼容 POSIX/bash | |
| nu (Nushell) | 結構化數據管道 (表格/JSON/CSV 原生)、Rust 編寫、現代 CLI 理念 | 新興、手動安裝 | 數據處理、結構化日誌分析、替代 jq/csvkit/awk |
sh (V7 Unix)。/etc/profile → ~/.profile (或 ~/.bash_profile/~/.bash_login)。if (expr) then ... endif)、歷史機制 (!!、!n)、別名 (alias)、檔名展開 (~、{a,b,c})、作業控制 (^Z, bg, fg, jobs)。|&)、命令行編輯 (vi/emacs 模式)、select 選單、[[ ... ]] 擴展測試、$(...) 命令替換 (現代標準)。#!/usr/bin/env bash
# 1. Shebang 指定解釋器,env 增加可移植性
set -euo pipefail
# 2. 嚴格模式:未定義變數報錯、管道任一失敗即失敗、命令非零退出即中止
readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# 3. 獲取腳本所在目錄 (兼容符號鏈接)
main() {
local input_file="${1:-/dev/stdin}"
local output_dir="${2:-/tmp/out}"
mkdir -p "$output_dir"
# 4. 讀取逐行處理 (IFS 保留前導尾隨空格)
while IFS= read -r line; do
process_line "$line" "$output_dir"
done < "$input_file"
}
process_line() {
local line="$1" out_dir="$2"
# 業務邏輯...
printf '%s\n' "Processed: $line" >> "$out_dir/result.log"
}
main "$@"
# 5. 入口調用,傳遞所有位置參數
| 類別 | 工具 | 用途 |
|---|---|---|
| 靜態分析/檢查 | ShellCheck | 語法錯誤、最佳實踐、安全隱患、可移植性問題 (VS Code/IDE 整合、CI 必跑) |
| shfmt | 格式化 (縮進、換行、空格),統一團隊風格 | |
| bash-language-server | LSP 支援:跳轉定義、懸停文檔、補全、診斷 | |
| 測試框架 | Bats (Bash Automated Testing System) | 單元測試、整合測試、TAP 輸出、CI 整合 |
| shunit2 | xUnit 風格、輕量、無依賴 | |
| ShellSpec | BDD 風格、豐富匹配器、並行執行 | |
| 除錯/追蹤 | bashdb / bash -x / set -x | 逐行追蹤、斷點、變數觀察 |
| xtrace 可視化 | PS4 格式化、輸出 JSON/結構化日誌 | |
| bpftrace / perf | 系統級動態追蹤 Shell 執行的系統調用 |