Shell 腳本的設定檔管理
在 Linux 系統管理與自動化腳本開發中,硬編碼(Hard-coding)變數值是初學者常犯的错误。當路徑變更、環境切換或團隊協作時,修改腳本內的固定值不僅效率低落,還容易引入錯誤。因此,將配置與邏輯分離,採用獨立的設定檔(Configuration File)來管理參數,是專業腳本編寫的必經之路。本文將介紹如何在 Bash 腳本中高效、安全地管理設定檔,並提供實用的範例。
為什麼需要設定檔?
想像一下,你寫了一個備份腳本,裡面寫死了 /home/user/backup 這個路徑。當你需要將備份目標改為 /mnt/backup 時,你必須開啟腳本、尋找並修改那一行。如果有十個腳本都引用了這個路徑,維護成本將呈指數級上升。
透過設定檔,我們可以將易變的參數(如路徑、主機 IP、帳號密碼、閾值等)抽離出來。腳本只需讀取設定檔即可執行,這樣不僅便於維護,也方便在不同環境(開發、測試、生產)之間切換配置,只需更換設定檔即可,無需修改腳本邏輯。
設定檔的格式選擇
在 Shell 腳本中,常見的設定檔格式主要有兩種:純文字鍵值對(Key-Value)和 JSON。對於大多數系統管理腳本,純文字鍵值對最為輕量且易於編輯。
優點:
- 易讀易寫:使用
key=value格式,人類閱讀無障礙。 - Shell 原生支援:可以直接使用
source或.指令載入,變數會自動進入當前環境。 - 效能高:解析速度極快,適合頻繁讀取的場景。
缺點:
- 安全性較低:若設定檔包含密碼,需額外處理權限。
- 缺乏結構化:不支援巢狀結構,複雜配置較難表達。
實戰範例:建立可執行的設定檔載入器
我們將建立一個標準化的腳本結構,包含設定檔載入、參數驗證與主邏輯。
首先,建立設定檔 config.env。注意,為了避免污染環境變數,我們建議使用特定的命名前綴。
# config.env
# 資料庫連線設定
DB_HOST="127.0.0.1"
DB_PORT="3306"
DB_NAME="myapp_production"
# 路徑設定
BACKUP_DIR="/var/backups/myapp"
LOG_DIR="/var/log/myapp"
# 布林值設定(使用 0/1 或 true/false)
ENABLE_LOGGING="true"
MAX_RETRIES="3"
接下來,撰寫主腳本 deploy.sh。這裡的關鍵技巧在於「載入設定檔」與「提供預設值」的結合。
#!/bin/bash
# deploy.sh - 範例部署腳本
set -euo pipefail
# 1. 定義設定檔路徑
CONFIG_FILE="./config.env"
# 2. 檢查設定檔是否存在
if [[ ! -f "$CONFIG_FILE" ]]; then
echo "錯誤:找不到設定檔 $CONFIG_FILE" >&2
exit 1
fi
# 3. 載入設定檔
# 使用 source 指令將設定檔中的變數載入當前環境
# 建議使用絕對路徑或相對路徑確保穩定性
source "$CONFIG_FILE"
# 4. 設定預設值(Default Values)
# 如果設定檔中未定義某些變數,使用預設值以避免腳本報錯
DB_HOST="${DB_HOST:-127.0.0.1}"
DB_PORT="${DB_PORT:-3306}"
ENABLE_LOGGING="${ENABLE_LOGGING:-false}"
# 5. 參數驗證
# 檢查必要參數是否為空
if [[ -z "$DB_NAME" ]]; then
echo "錯誤:DB_NAME 未設定" >&2
exit 1
fi
if [[ ! -d "$BACKUP_DIR" ]]; then
echo "警告:備份目錄 $BACKUP_DIR 不存在,正在建立..." >&2
mkdir -p "$BACKUP_DIR"
fi
# 6. 主邏輯
echo "開始部署程序..."
echo "連線至資料庫: $DB_HOST:$DB_PORT/$DB_NAME"
echo "備份目錄: $BACKUP_DIR"
if [[ "$ENABLE_LOGGING" == "true" ]]; then
echo "日誌功能已啟用"
# 模擬寫入日誌
echo "$(date '+%Y-%m-%d %H:%M:%S') - Deploy started" >> "${LOG_DIR}/deploy.log"
fi
echo "部署完成!"
權限與安全性注意事項
當設定檔包含敏感資訊(如密碼、API Key)時,必須嚴格控制檔案權限。在 Ubuntu 或 Debian 系統上,請確保設定檔僅所有者可讀寫:
chmod 600 config.env
chown $USER:$USER config.env
此外,切勿將包含密碼的設定檔提交至 Git 等版本控制系統。建議使用 .gitignore 排除設定檔,或透過環境變數(如 export DB_PASSWORD=secret)在執行時注入。
常見問題
1. 為什麼使用 source 而不是 bash config.env?
使用 bash config.env 會在子殼層(Subshell)中執行腳本,因此變數不會回傳到父腳本中,導致主腳本無法讀取到設定值。source 或 . 指令會在當前殼層執行,變數會保留在當前環境中。
2. 如何處理設定檔中的註解與空行?
source 指令會忽略以 # 開頭的行以及空行,因此你可以在設定檔中自由添加註解說明,腳本仍會正確執行。這使得設定檔兼具文檔與配置的功能。
小結
透過將配置與邏輯分離,我們的 Shell 腳本變得更加靈活、易於維護且具備更高的可移植性。掌握設定檔的管理技巧,是邁向專業 Linux 自動化腳本開發的重要一步。建議在未來的開發中,始終遵循「配置外置」的原則,並妥善處理權限與安全性問題。