Bash 中的關聯陣列(Associative Array) 文章首圖

Bash 中的關聯陣列(Associative Array)

Bash 中的關聯陣列(Associative Array)

在 Bash 腳本開發中,陣列(Array)是最常用的資料結構之一。然而,傳統的 Bash 陣列僅支援基於整數索引的存取,這意味著我們無法直接使用字串鍵(Key)來查找對應的值。當我們需要處理類似資料庫鍵值對(Key-Value Pair)的資料時,傳統的陣列顯得力不從心。

從 Bash 4.0 版本開始,官方引入了關聯陣列(Associative Array),允許我們使用自定義的字串作為索引。這使得 Bash 腳本在處理配置檔解析、快取機制或簡單的名稱對照表時,變得更加直觀且高效。本文將詳細介紹如何在 Ubuntu 22.04 或 Debian 12 環境中正確使用關聯陣列。

為什麼需要關聯陣列?

想像一下,你正在寫一個腳本來管理伺服器上的使用者資訊。如果使用傳統陣列,你可能需要維護兩個平行的陣列:一個存 ID,一個存名稱,並依賴索引位置來對應它們。這種方式不僅容易出錯,而且在資料量大時效率低落。

關聯陣列允許你直接透過「名稱」來存取「資料」,例如 user_info["alice"] 直接返回 "alice@example.com",邏輯清晰且易於維護。

基本語法與宣告

在 Bash 中使用關聯陣列前,必須先明確宣告。這是許多初學者容易忽略的步驟,未宣告直接使用會導致腳本報錯。

# 宣告一個名為 user_db 的關聯陣列
declare -A user_db

# 賦值操作
user_db["alice"]="alice@example.com"
user_db["bob"]="bob@example.com"
user_db["charlie"]="charlie@example.com"

這裡的 -A 參數告訴 Bash 這是一個 Associative array。如果你忘記宣告,直接進行賦值,Bash 會將其視為普通字串或產生錯誤,具體取決於 Bash 的版本與設定。

實用操作範例

宣告並填入資料後,我們可以進行讀取、遍歷與檢查等常見操作。以下是一個完整的實用腳本範例,模擬簡單的用戶配置管理系統。

#!/bin/bash

# 1. 初始化關聯陣列
declare -A config

# 2. 填入測試資料
config["hostname"]="ubuntu-server-01"
config["ip_address"]="192.168.1.100"
config["os"]="Ubuntu 22.04"
config["status"]="active"

# 3. 讀取特定鍵的值
echo "當前主機名稱: ${config[hostname]}"
echo "IP 位址: ${config[ip_address]}"

# 4. 檢查鍵是否存在
if [[ -v config["ip_address"] ]]; then
    echo "IP 位址資料存在。"
else
    echo "錯誤:找不到 IP 位址。"
fi

# 5. 刪除特定鍵
unset config["status"]

# 6. 再次檢查是否存在
if [[ -v config["status"] ]]; then
    echo "狀態資料仍存在。"
else
    echo "狀態資料已刪除。"
fi

# 7. 遍歷所有鍵與值
echo -e "\n--- 所有配置項目 ---"
for key in "${!config[@]}"; do
    echo "$key = ${config[$key]}"
done

執行結果:

當前主機名稱: ubuntu-server-01
IP 位址: 192.168.1.100
IP 位址資料存在。
狀態資料已刪除。

--- 所有配置項目 ---
hostname = ubuntu-server-01
ip_address = 192.168.1.100
os = Ubuntu 22.04

在範例中,-v 選項用於檢查變數是否已設定(即鍵是否存在)。遍歷時,${!config[@]} 獲取所有鍵,${config[$key]} 獲取對應的值。

常見問題與注意事項

1. Bash 版本相容性問題

關聯陣列僅在 Bash 4.0+ 中支援。雖然 Ubuntu 22.04 和 Debian 12 預設使用的 Bash 版本均高於 4.0(通常為 5.x),但如果你需要在較舊的系統(如 CentOS 7 或 Ubuntu 18.04 預設環境)上運行腳本,可能會遇到錯誤。

解決方案: 在腳本開頭檢查 Bash 版本:

if [[ "${BASH_VERSINFO[0]}" -lt 4 ]]; then
    echo "錯誤:此腳本需要 Bash 4.0 或更高版本。"
    exit 1
fi

2. 特殊字元與空格處理

當鍵(Key)或值(Value)包含空格或特殊字元時,務必使用雙引號包覆,否則腳本可能因詞法分析錯誤而崩潰。

錯誤示範:

# 錯誤:空格會導致解析失敗
config[my key]="value"

正確示範:

# 正確:使用雙引號包覆鍵名
config["my key"]="value"
config["host name"]="server 01"

小結

關聯陣列是 Bash 腳本中處理鍵值對資料的強大工具,它補足了傳統數值索引陣列的不足,讓腳本更具可讀性與維護性。透過 declare -A 宣告、[] 存取、-v 檢查以及 ${!arr[@]} 遍歷,你可以輕鬆構建複雜的配置管理邏輯。

記住,始終確保你的運行環境支援 Bash 4.0+,並小心處理包含空格的字串。掌握這些技巧後,你的 Shell 腳本將能處理更複雜的資料結構,大幅提升自動化任務的效率。