Bash 完整功能的 CLI 工具開發
許多 Linux 使用者認為 Bash 僅能用來寫簡單的自動化腳本,但事實上,透過善用 Bash 的內建特性與標準工具鏈,我們能開發出結構嚴謹、錯誤處理完善的專業級 CLI(Command Line Interface)工具。這篇文章將引導你從零開始,打造一個具備參數解析、錯誤檢查與進度提示的完整 Bash 工具。
核心架構設計
一個專業的 CLI 工具應具備以下特徵:
- 清晰的用法說明:使用者能輕易得知如何執行。
- 嚴謹的參數驗證:避免錯誤輸入導致系統異常。
- 良好的錯誤處理:當指令失敗時能給出明確提示。
- 可維護的結構:程式碼模組化,便於後續擴充。
我們將建立一個名為 sys-monitor 的腳本,用於簡化系統資源監控。
實作步驟
1. 腳本開頭與環境檢查
首先,定義腳本元數據並檢查執行環境。使用 #!/usr/bin/env bash 確保跨平台相容性,並啟用嚴格模式 set -euo pipefail 來即時捕捉錯誤。
#!/usr/bin/env bash
# 嚴格模式:遇到錯誤立即停止,未定義變數視為錯誤,管道錯誤傳遞
set -euo pipefail
# 腳本名稱與版本
readonly SCRIPT_NAME="sys-monitor"
readonly VERSION="1.0.0"
# 顏色定義,提升視覺體驗
readonly RED='\033[0;31m'
readonly GREEN='\033[0;32m'
readonly NC='\033[0m' # No Color
# 輔助函數:輸出錯誤訊息並退出
die() {
echo -e "${RED}ERROR: $1${NC}" >&2
exit 1
}
# 輔助函數:輸出成功訊息
success() {
echo -e "${GREEN}SUCCESS: $1${NC}"
}
2. 參數解析邏輯
使用 getopts 處理短選項,並支援 --help 與 --version。這是 Bash 開發 CLI 的標準做法。
# 預設參數
MODE="cpu"
VERBOSE=false
usage() {
cat <<EOF
Usage: $SCRIPT_NAME [OPTIONS]
Options:
-m, --mode MODE Monitoring mode: 'cpu' or 'mem' (default: cpu)
-v, --verbose Enable verbose output
-h, --help Show this help message
-V, --version Show version information
Examples:
$SCRIPT_NAME -m cpu
$SCRIPT_NAME --mode mem -v
EOF
exit 0
}
# 解析參數
while [[ $# -gt 0 ]]; do
case $1 in
-m|--mode)
MODE="$2"
shift 2
;;
-v|--verbose)
VERBOSE=true
shift
;;
-h|--help)
usage
;;
-V|--version)
echo "$SCRIPT_NAME version $VERSION"
exit 0
;;
*)
die "Unknown option: $1"
;;
esac
done
3. 核心功能實現
根據模式執行不同的監控邏輯。這裡示範如何結合 top、free 等標準工具,並處理可能的錯誤。
# 檢查依賴工具是否存在
check_dependencies() {
local deps=("top" "free" "awk")
for dep in "${deps[@]}"; do
if ! command -v "$dep" &> /dev/null; then
die "Required tool '$dep' is not installed."
fi
done
}
# CPU 監控邏輯
monitor_cpu() {
echo "Monitoring CPU usage..."
# 使用 top 的批處理模式獲取 CPU 閒置率
local idle
idle=$(top -bn1 | grep "Cpu(s)" | awk '{print $8}' | cut -d'%' -f1)
if [[ -z "$idle" ]]; then
die "Failed to parse CPU usage."
fi
local usage
usage=$(echo "100 - $idle" | bc)
echo "Current CPU Idle: ${idle}%"
echo "Current CPU Usage: ${usage}%"
if (( $(echo "$usage > 90" | bc -l) )); then
echo -e "${RED}Warning: High CPU usage detected!${NC}"
fi
}
# 記憶體監控邏輯
monitor_mem() {
echo "Monitoring Memory usage..."
local mem_info
mem_info=$(free | awk '/^Mem:/ {printf "%.2f", $3/$2 * 100}')
echo "Memory Usage: ${mem_info}%"
if (( $(echo "$mem_info > 90" | bc -l) )); then
echo -e "${RED}Warning: High Memory usage detected!${NC}"
fi
}
# 主執行流程
main() {
check_dependencies
# 驗證 MODE 參數
if [[ "$MODE" != "cpu" && "$MODE" != "mem" ]]; then
die "Invalid mode: $MODE. Please choose 'cpu' or 'mem'."
fi
if $VERBOSE; then
echo "[Verbose] Running in $MODE mode..." >&2
fi
case $MODE in
cpu) monitor_cpu ;;
mem) monitor_mem ;;
esac
success "Monitoring completed."
}
# 執行 main 函數
main "$@"
常見問題與解決方案
Q1: 腳本在執行時出現 command not found 錯誤?
這通常發生在 set -euo pipefail 模式下,若依賴的工具(如 bc 或 awk)未安裝,腳本會立即終止。解決方案是在 check_dependencies 函數中明確檢查,並提供安裝指引。例如:sudo apt install bc。
Q2: 如何讓腳本在背景運行而不產生輸出?
若希望腳本靜默執行,可在呼叫時將標準輸出與標準錯誤重導向至 /dev/null,例如:./sys-monitor -m cpu > /dev/null 2>&1 &。注意,這會隱藏錯誤訊息,僅建議用於已知穩定的自動化任務。
小結
透過這篇文章,我們建立了一個具備參數解析、依賴檢查與錯誤處理的 Bash CLI 工具。關鍵在於善用 set -euo pipefail 確保程式碼的健壯性,並利用 getopts 提供使用者友好的介面。掌握這些技巧後,你將能開發出更專業、易於維護的 Bash 工具,大幅提升日常系統管理與開發的效率。建議讀者將此模板複製並根據自身需求擴充,例如加入日誌記錄或 JSON 輸出功能。