Khai báo và Đặc điểm của Mảng trong Bash
Trong lập trình kịch bản Shell, cấu trúc mảng cho phép nhóm nhiều giá trị lại thành một biến duy nhất. Khác với các ngôn ngữ có kiểu dữ liệu tĩnh, Bash sử dụng kiểu yếu (weakly typed), nghĩa là các phần tử trong cùng một mảng có thể đồng thời là số nguyên, chuỗi ký tự hoặc đường dẫn file mà không bị lỗi biên dịch. Về mặt kiến trúc, Bash chỉ hỗ trợ mảng một chiều, chỉ số (index) mặc định bắt đầu từ 0, và không áp đặt giới hạn cứng về số lượng phần tử.
Cú pháp khai báo chuẩn có dạng:
ten_mang=(phan_tu_1 phan_tu_2 phan_tu_3 ...)
Ví dụ minh họa cơ bản:
diem_thi=(85 92 76 88 95)
# Hỗ trợ trộn lẫn nhiều kiểu dữ liệu
thong_tin_srv=("web-node-1" 8080 "running")
Các phương pháp khởi tạo và gán giá trị
Người dùng có thể cập nhật dữ liệu vào mảng theo nhiều cách linh hoạt tùy theo ngữ cảnh thực thi:
- Gán từng vị trí cụ thể: Hữu ích khi cần khởi tạo mảng dần dần hoặc sửa đổi giá trị tại một chỉ số nhất định.
config[0]="staging"
config[1]=3306
config[2]="readonly"
- Gán hàng loạt hoặc khởi tạo từ đầu: Các giá trị được cách nhau bằng dấu cách. Nếu không khai báo đầy đủ chỉ số liên tiếp, Bash sẽ tự động bổ sung khoảng trống.
# Khởi tạo tĩnh
roles=("admin" "developer" "auditor" "guest")
# Mảng thưa (Sparse Array): bỏ qua các index trung gian
priority_list=(10 25 [99]="critical_task")
# Nhận đầu ra của lệnh hệ thống
active_procs=($(ps -ef | grep nginx | awk '{print $2}'))
tmp_files=($(find /var/tmp -type f -name "*.log"))
Truy xuất và trích xuất dữ liệu
Để đọc giá trị tại một vị trí, sử dụng cú pháp tham chiếu `"${ten_mang[chỉ_số]}"`. Nếu chỉ số vượt quá giới hạn hoặc không tồn tại, Shell trả về chuỗi rỗng thay vì báo lỗi.
echo ${roles[2]} # Kết quả: auditor
Bash cung cấp các toán tử đặc biệt để thao tác nhanh với toàn bộ mảng hoặc thông số cấu hình của nó:
${roles[*]}hoặc${roles[@]}: Trả về danh sách tất cả phần tử.${#roles[@]}: Đếm tổng số lượng phần tử hiện có.${!roles[@]}: Liệt kê danh sách các chỉ số (key) đang được gắn giá trị.${roles[@]:start:count}: Cắt mảng (slice), trả vềcountphần tử bắt đầu từ vị trístart.
echo "${#priority_list[@]}" # In ra số lượng phần tử
echo "${!priority_list[@]}" # In ra các index hiện hữu: 0 1 99
echo "${roles[@]:1:2}" # Lấy 2 phần tử bắt đầu từ index 1: developer auditor
Truyền mảng vào hàm và xử lý tham số
Khi cần xử lý tập hợp dữ liệu bên trong một hàm Bash, việc truyền trực tiếp tên biến sẽ không hoạt động như mong đợi. Thay vào đó, hãy sử dụng tham chiếu đầy đủ bằng dấu `*` hoặc `@`. Bên trong thân hàm, các tham số được nhận qua biến vị trí `$1`, `$2`,... Để tái cấu trúc chúng thành mảng cục bộ, cần bao bọc danh sách tham số trong dấu ngoặc đơn `()`.
Lưu ý quan trọng về tham số vị trí: Bash chỉ nhận diện `$0` đến `$9` bằng cách viết trực tiếp. Khi cần truy cập từ tham số thứ 10 trở đi, bắt buộc phải dùng dấu ngoặc nhọn `${10}`, `${11}`...
xu_ly_danh_sach() {
# Chuyển đổi danh sách tham số vị trí thành mảng cục bộ
local local_arr=($@)
echo "Tổng số mục nhận được: ${#local_arr[@]}"
for entry in "${local_arr[@]}"; do
echo "Xử lý: $entry"
done
}
# Gọi hàm và truyền toàn bộ mảng dưới dạng tham số
xu_ly_danh_sach "${roles[@]}"