用 Bash 解析 JSON 設定檔
在日常的 Linux 系統管理與自動化腳本開發中,我們經常需要讀取外部設定檔。雖然傳統做法多使用 .conf 或 .ini 格式,但近年來 JSON 因其結構嚴謹、支援巢狀資料且人類可讀性高,已成為許多現代應用程式(如 Kubernetes、Docker Compose、Ansible)的首選配置格式。
許多初學者會認為 Bash 不擅長處理 JSON,必須依賴 Python 或 Node.js 才能完成。事實上,雖然 Bash 原生不支援 JSON 解析,但透過搭配輕量級的指令行工具 jq,我們可以在 Shell 腳本中高效、簡潔地提取所需數據。本文将介紹如何在 Ubuntu 22.04 或 Debian 12 環境中,利用 jq 實現 JSON 設定檔的解析。
環境準備與安裝
在開始編寫腳本之前,請確保您的系統已安裝 jq。對於 Ubuntu 22.04 和 Debian 12 使用者,安裝過程非常簡單。打開終端機,執行以下指令:
sudo apt update
sudo apt install -y jq
安裝完成後,您可以輸入 jq --version 確認安裝狀態。若顯示版本號(例如 jq-1.6),則表示環境已就緒。
實戰範例:解析巢狀 JSON 設定檔
假設我們有一個名為 config.json 的設定檔,內容如下。這個檔案模擬了一個應用程式的資料庫連線與日誌配置,包含巢狀結構與陣列資料。
{
"app_name": "MyApp",
"version": "1.2.0",
"database": {
"host": "192.168.1.100",
"port": 5432,
"credentials": {
"username": "admin",
"password": "secret123"
}
},
"features": ["logging", "metrics", "alerts"],
"debug": true
}
1. 提取基本鍵值
若我們只想取得應用程式名稱,可以使用 jq 的簡易查詢語法。在 Shell 腳本中,通常會將 jq 的輸出結果賦值給變數。
#!/bin/bash
CONFIG_FILE="config.json"
# 檢查檔案是否存在
if [[ ! -f "$CONFIG_FILE" ]]; then
echo "錯誤:找不到設定檔 $CONFIG_FILE"
exit 1
fi
# 提取 app_name
APP_NAME=$(jq -r '.app_name' "$CONFIG_FILE")
echo "應用程式名稱: $APP_NAME"
這裡關鍵參數 -r (raw output) 非常重要。若不加 -r,jq 會輸出帶有雙引號的字串 "MyApp",而加上後則輸出純文字 MyApp,方便後續字串處理。
2. 提取巢狀資料
JSON 的強大之處在於其層級結構。若要提取資料庫的主機位址,只需使用點號(.)或方括號([])來導航路徑。
# 提取資料庫主機位址
DB_HOST=$(jq -r '.database.host' "$CONFIG_FILE")
echo "資料庫主機: $DB_HOST"
# 提取密碼(注意:實際生產環境應避免明文儲存密碼,此處僅為教學示範)
DB_PASS=$(jq -r '.database.credentials.password' "$CONFIG_FILE")
echo "資料庫密碼: $DB_PASS"
3. 處理陣列與過濾
若需要檢查某個功能是否啟用,或遍歷陣列中的項目,jq 提供了強大的過濾功能。例如,我們想確認 features 陣列中是否包含 logging,並將其轉換為單行字串輸出。
# 將陣列轉換為以逗號分隔的字串
FEATURES_STR=$(jq -r '.features | join(",")' "$CONFIG_FILE")
echo "啟用的功能: $FEATURES_STR"
# 檢查特定元素是否存在
if jq -e '.features | index("metrics")' "$CONFIG_FILE" > /dev/null; then
echo "Metrics 功能已啟用"
else
echo "Metrics 功能未啟用"
fi
其中 -e 參數用於判斷查詢是否有結果,若無結果則回傳非零狀態碼,非常適合用於 if 條件判斷。
常見問題與注意事項
在使用 Bash 解析 JSON 時,開發者常會遇到以下兩個問題:
1. 為什麼輸出結果帶有雙引號?
這是因為 JSON 標準規定字串必須以雙引號包裹。jq 預設會遵循此標準輸出。若您需要在 Shell 變數中直接使用該值(例如拼接路徑或傳遞參數),務必加上 -r 參數以移除外層引號。
2. 遇到特殊字元或 Unicode 編碼時該如何處理?
jq 預設會將非 ASCII 字元(如中文)轉換為 Unicode 編碼序列。若您希望直接顯示中文,可以加上 -j 參數(raw input/output 的組合變體,視版本而定)或使用 --raw-output。此外,若 JSON 檔案包含單引號或特殊 Shell 字元,建議使用 jq -R 讀取原始字串並手動處理,或確保腳本使用雙引號包裹變數,防止 Shell 誤解字元。
小結
雖然 Bash 本身不支援 JSON 解析,但透過整合 jq 這個強大的工具,我們能夠以極少的程式碼完成複雜的資料提取工作。本文介紹了如何安裝 jq,並展示了提取基本值、導航巢狀結構以及處理陣列的實戰技巧。
掌握這些技巧後,您將能更靈活地處理現代化的設定檔格式,提升腳本的穩定性與可讀性。建議您在實際專案中,將 JSON 設定檔的路徑與權限管理納入考量,確保資料的安全性。