Bạn đã bao giờ thấy mình phải quản lý hàng chục biến riêng lẻ trong một kịch bản shell script chưa? Việc theo dõi, cập nhật và xử lý từng biến một cách thủ công không chỉ tốn thời gian mà còn dễ gây ra lỗi. Đây là lúc mà mảng (array) trong Bash phát huy sức mạnh của mình. Mảng cho phép bạn lưu trữ nhiều giá trị trong cùng một biến duy nhất, giúp mã nguồn trở nên gọn gàng, dễ đọc và hiệu quả hơn rất nhiều. Thay vì loay hoay với `bien1`, `bien2`, `bien3`, bạn có thể gom chúng vào một cấu trúc dữ liệu duy nhất. Bài viết này sẽ là kim chỉ nam, dẫn dắt bạn từ những khái niệm cơ bản nhất về mảng trong Bash, cách khai báo, thao tác, cho đến các ví dụ thực tiễn và những phương pháp tốt nhất để bạn có thể tự tin áp dụng vào công việc của mình.
Giới thiệu về mảng trong Bash
Trong thế giới lập trình kịch bản Shell, việc xử lý dữ liệu là một công việc diễn ra hàng ngày. Đôi khi, bạn cần làm việc với một danh sách các tệp, một loạt tên người dùng, hay một chuỗi các địa chỉ IP. Nếu chỉ sử dụng các biến đơn lẻ, kịch bản của bạn sẽ nhanh chóng trở nên phức tạp và khó bảo trì. Thử tưởng tượng bạn phải tạo một biến cho mỗi tên tệp trong một thư mục chứa hàng trăm tệp, đó thực sự là một cơn ác mộng.
Vấn đề cốt lõi ở đây là sự thiếu hiệu quả trong việc quản lý một tập hợp dữ liệu có liên quan. Khi số lượng phần tử tăng lên, việc quản lý chúng một cách riêng lẻ trở nên không khả thi. Đây chính là lúc mảng trong Bash xuất hiện như một giải pháp cứu cánh. Mảng cung cấp một cách thức thông minh để nhóm các giá trị liên quan lại với nhau dưới một cái tên chung, giúp bạn truy cập và thao tác chúng một cách dễ dàng.
Bài viết này sẽ đi sâu vào mọi khía cạnh của mảng trong Bash. Chúng ta sẽ bắt đầu từ khái niệm cơ bản “Script là gì“, tìm hiểu cú pháp khai báo, cách truy cập từng phần tử, các thao tác thêm, sửa, xóa. Sau đó, chúng ta sẽ xem xét các ví dụ minh họa cụ thể và khám phá những ứng dụng thực tế của mảng trong các kịch bản tự động hóa hàng ngày. Cuối cùng, bài viết sẽ chỉ ra các lỗi thường gặp và những phương pháp tốt nhất để bạn làm việc với mảng một cách chuyên nghiệp.
Khái niệm và cú pháp khai báo mảng trong Bash
Để sử dụng thành thạo mảng, trước tiên chúng ta cần hiểu rõ bản chất của nó và cách khai báo đúng cú pháp trong môi trường Bash. Đây là nền tảng vững chắc giúp bạn tránh được những lỗi không đáng có và xây dựng các kịch bản hiệu quả hơn. Hãy cùng khám phá khái niệm và các cách khởi tạo mảng ngay sau đây.

Mảng là gì trong Bash?
Trong Bash, mảng là một biến đặc biệt có khả năng lưu trữ nhiều giá trị cùng một lúc. Hãy hình dung mảng giống như một tủ hồ sơ có nhiều ngăn kéo được đánh số. Mỗi ngăn kéo (phần tử) chứa một giá trị (dữ liệu), và bạn có thể truy cập vào từng ngăn kéo thông qua số thứ tự của nó (chỉ số – index).
Việc sử dụng mảng mang lại rất nhiều lợi ích. Đầu tiên, nó giúp mã nguồn của bạn trở nên ngăn nắp và dễ quản lý hơn. Thay vì phải khai báo `file1=”a.txt”`, `file2=”b.txt”`, `file3=”c.txt”`, bạn có thể gom tất cả vào một mảng duy nhất: files=(“a.txt” “b.txt” “c.txt”). Thứ hai, mảng cho phép bạn dễ dàng duyệt qua tất cả các phần tử bằng vòng lặp, giúp tự động hóa các tác vụ lặp đi lặp lại một cách hiệu quả. Cuối cùng, nó giúp việc truyền dữ liệu giữa các hàm trong script trở nên đơn giản hơn.
Cú pháp khai báo và khởi tạo mảng
Trong Bash, có nhiều cách để khai báo và khởi tạo một mảng. Cách phổ biến nhất là sử dụng dấu ngoặc đơn `()` và các phần tử được phân tách bởi dấu cách. Cú pháp cơ bản như sau: `ten_mang=(gia_tri1 gia_tri2 gia_tri3)`. Ví dụ, để tạo một mảng chứa danh sách các loại trái cây, bạn có thể viết: `trai_cay=(“Táo” “Cam” “Xoài”)`.
Bạn cũng có thể khởi tạo một mảng rỗng và sau đó thêm các phần tử vào. Cú pháp để tạo mảng rỗng rất đơn giản: `mang_rong=()`. Ngoài ra, bạn có thể gán giá trị cho từng phần tử thông qua chỉ số của nó. Lưu ý rằng chỉ số của mảng trong Bash bắt đầu từ 0. Ví dụ: `he_dieu_hanh[0]=”Ubuntu”`, he_dieu_hanh[1]=”CentOS”, `he_dieu_hanh[2]=”Debian”`.

Bash hỗ trợ hai loại mảng chính. Loại thứ nhất là mảng số chỉ (indexed array), là loại chúng ta vừa tìm hiểu, sử dụng các số nguyên không âm làm chỉ số. Đây là loại mảng mặc định và được sử dụng phổ biến nhất. Loại thứ hai là mảng liên kết (associative array), cho phép bạn sử dụng chuỗi ký tự (string) làm khóa (key) thay vì chỉ số số. Để sử dụng mảng liên kết, bạn cần khai báo nó một cách tường minh bằng lệnh `declare -A`. Ví dụ: `declare -A user_info`, sau đó gán giá trị: `user_info[name]=”Duc”`, `user_info[job]=”Developer”`.
Các cách truy cập và thao tác với phần tử mảng
Sau khi đã biết cách khai báo mảng, bước tiếp theo là học cách truy cập và làm việc với các phần tử bên trong nó. Việc truy xuất dữ liệu, gán giá trị mới hay duyệt qua toàn bộ mảng là những thao tác cơ bản và cực kỳ quan trọng khi bạn viết bất kỳ kịch bản nào có sử dụng mảng. Hãy cùng đi vào chi tiết các cú pháp cần thiết.
Truy cập phần tử mảng
Để truy cập một phần tử cụ thể trong mảng, bạn cần sử dụng cú pháp `${ten_mang[chi_so]}`. Trong đó, `ten_mang` là tên của mảng và `chi_so` là vị trí của phần tử bạn muốn lấy, bắt đầu từ 0. Ví dụ, nếu chúng ta có mảng trai_cay=(“Táo” “Cam” “Xoài”), để lấy giá trị “Cam”, bạn sẽ dùng `${trai_cay[1]}`.
Khi bạn muốn lấy toàn bộ các phần tử của mảng, Bash cung cấp hai cú pháp đặc biệt: `${ten_mang[@]}` và `${ten_mang[*]}`. Cả hai đều trả về tất cả các phần tử của mảng. Tuy nhiên, có một sự khác biệt tinh tế khi chúng được đặt trong dấu ngoặc kép. `”${ten_mang[@]}”` sẽ mở rộng thành các từ riêng biệt (`”gia_tri1″` `”gia_tri2″`…), rất hữu ích khi duyệt mảng trong vòng lặp. Ngược lại, `”${ten_mang[*]}”` sẽ mở rộng thành một chuỗi duy nhất chứa tất cả các phần tử, được phân tách bởi ký tự đầu tiên trong biến `IFS` (mặc định là dấu cách). Để đảm bảo an toàn và đúng đắn trong hầu hết các trường hợp, bạn nên ưu tiên sử dụng `”${ten_mang[@]}”`.

Thao tác với phần tử mảng
Việc đọc giá trị từ một phần tử rất đơn giản, như chúng ta đã thấy ở trên. Để gán hoặc cập nhật giá trị cho một phần tử, bạn chỉ cần thực hiện phép gán thông thường: `ten_mang[chi_so]=gia_tri_moi`. Ví dụ, để thay đổi “Cam” thành “Chanh” trong mảng `trai_cay`, bạn viết: `trai_cay[1]=”Chanh”`.
Thao tác quan trọng nhất khi làm việc với mảng là duyệt qua tất cả các phần tử để xử lý chúng. Vòng lặp for là công cụ lý tưởng cho việc này. Cú pháp phổ biến và an toàn nhất là: `for item in “${ten_mang[@]}”; do … done`. Ví dụ, để in ra tất cả các loại trái cây, mỗi loại trên một dòng: `for qua in “${trai_cay[@]}”; do echo “Tôi thích ăn: $qua”; done`. Việc sử dụng dấu ngoặc kép quanh `”${ten_mang[@]}”` đảm bảo rằng các phần tử có chứa dấu cách vẫn được xử lý chính xác như một phần tử duy nhất.
Ngoài vòng lặp `for`, bạn cũng có thể sử dụng vòng lặp `while` kết hợp với một biến đếm để duyệt mảng. Tuy nhiên, cách này thường dài dòng và ít phổ biến hơn. Vòng lặp `for` với cú pháp `[@]` vẫn là lựa chọn hàng đầu vì sự đơn giản và hiệu quả của nó trong hầu hết các tình huống.
Thêm, sửa và xóa phần tử trong mảng Bash
Một khi mảng đã được tạo, nhu cầu thay đổi nó là điều không thể tránh khỏi. Bạn có thể cần thêm dữ liệu mới, cập nhật thông tin cũ, hoặc loại bỏ những phần tử không còn cần thiết. Bash cung cấp các cú pháp trực quan để thực hiện những tác vụ này, giúp bạn quản lý mảng một cách linh hoạt trong suốt vòng đời của kịch bản.

Thêm phần tử vào mảng
Cách đơn giản nhất để thêm một hoặc nhiều phần tử mới vào cuối mảng là sử dụng toán tử `+=`. Cú pháp này rất gọn gàng và dễ đọc: `ten_mang+=(phan_tu_moi1 phan_tu_moi2)`. Ví dụ, nếu có mảng `servers=(“web01” “db01”)` và bạn muốn thêm một server mới là “app01”, bạn chỉ cần viết: `servers+=(“app01”)`.
Nếu bạn muốn thêm một phần tử vào một vị trí cụ thể (chỉ số xác định) trong mảng, bạn có thể thực hiện bằng cách gán trực tiếp. Tuy nhiên, cần lưu ý rằng nếu chỉ số đó đã tồn tại, giá trị cũ sẽ bị ghi đè. Nếu bạn muốn “chèn” một phần tử mà không làm mất dữ liệu cũ, bạn sẽ cần thực hiện một vài thao tác phức tạp hơn, chẳng hạn như tạo một mảng mới bằng cách kết hợp các lát cắt (slice) của mảng cũ. Ví dụ: `new_array=(“${old_array[@]:0:index}” “new_element” “${old_array[@]:index}”)`.
Sửa đổi và xóa phần tử mảng
Việc sửa đổi giá trị của một phần tử đã tồn tại là thao tác cơ bản nhất. Bạn chỉ cần truy cập phần tử đó thông qua chỉ số và gán cho nó một giá trị mới. Ví dụ, để cập nhật server `web01` thành `web02` trong mảng `servers`, bạn dùng lệnh: `servers[0]=”web02″`.
Để xóa một phần tử cụ thể khỏi mảng, bạn sử dụng lệnh `unset`. Cú pháp là `unset ten_mang[chi_so]`. Ví dụ, để xóa server `db01` (ở chỉ số 1) khỏi mảng `servers`, bạn chạy lệnh: `unset servers[1]`. Điều quan trọng cần lưu ý là `unset` chỉ loại bỏ phần tử và giá trị của nó, nhưng không sắp xếp lại các chỉ số của mảng. Mảng sẽ bị “thủng” một lỗ ở vị trí đó. Nếu bạn muốn xóa toàn bộ mảng và giải phóng bộ nhớ, chỉ cần dùng `unset ten_mang` mà không cần chỉ số.
Để reset một mảng về trạng thái rỗng mà không xóa hoàn toàn biến mảng, bạn có thể gán lại nó thành một mảng rỗng: `ten_mang=()`. Thao tác này sẽ xóa tất cả các phần tử nhưng biến mảng vẫn tồn tại, sẵn sàng để bạn thêm các phần tử mới vào sau đó.
Ví dụ minh họa sử dụng mảng trong shell script
Lý thuyết sẽ trở nên dễ hiểu hơn rất nhiều khi được áp dụng vào một ví dụ thực tế. Bây giờ, chúng ta sẽ cùng nhau xây dựng một kịch bản shell script đơn giản để quản lý danh sách các website cần kiểm tra trạng thái. Kịch bản này sẽ khai báo một mảng chứa các tên miền, sau đó duyệt qua từng tên miền và sử dụng lệnh `curl` để kiểm tra xem website có phản hồi hay không.

Đây là mã script mẫu:
#!/bin/bash
# Khai báo một mảng chứa danh sách các website cần kiểm tra
websites=("google.com" "github.com" "buimanhduc.com" "non-existent-site.org")
echo "Bắt đầu kiểm tra trạng thái các website..."
echo "----------------------------------------"
# Duyệt qua từng phần tử trong mảng 'websites'
for site in "${websites[@]}"; do
echo -n "Đang kiểm tra $site... "
# Sử dụng curl để gửi yêu cầu và ẩn output, chỉ lấy mã trạng thái HTTP
# --output /dev/null: không hiển thị nội dung trả về
# --silent: im lặng, không hiển thị thanh tiến trình
# --head: chỉ lấy phần header, không lấy body, nhanh hơn
# --write-out '%{http_code}': in ra mã trạng thái HTTP
status_code=$(curl --output /dev/null --silent --head --write-out '%{http_code}' "$site")
# Kiểm tra mã trạng thái và thông báo kết quả
if [ "$status_code" -eq 200 ] || [ "$status_code" -eq 301 ] || [ "$status_code" -eq 302 ]; then
echo "✅ Hoạt động (Code: $status_code)"
else
echo "❌ Gặp sự cố (Code: $status_code)"
fi
done
echo "----------------------------------------"
echo "Hoàn tất kiểm tra."
Hãy cùng phân tích từng bước hoạt động của script trên. Đầu tiên, chúng ta khai báo một mảng tên là `websites` chứa bốn tên miền. Sau đó, script sử dụng vòng lặp for site in “${websites[@]}” để lặp qua từng tên miền trong mảng. Bên trong vòng lặp, lệnh `curl` được gọi để gửi một yêu cầu `HEAD` đến website. Kết quả trả về là mã trạng thái HTTP (ví dụ: 200 cho OK, 404 cho Not Found) được lưu vào biến `status_code`. Cuối cùng, một câu lệnh `if` sẽ kiểm tra giá trị của `status_code` để đưa ra thông báo tương ứng: “Hoạt động” hay “Gặp sự cố”.
Lợi ích của việc sử dụng mảng trong kịch bản này là rất rõ ràng. Nếu bạn muốn thêm hoặc bớt website cần kiểm tra, bạn chỉ cần chỉnh sửa một dòng duy nhất, đó là dòng khai báo mảng `websites`. Bạn không cần phải thay đổi logic của vòng lặp hay các phần khác của script. Điều này làm cho kịch bản trở nên cực kỳ linh hoạt, dễ bảo trì và mở rộng. Nếu không có mảng, bạn sẽ phải lặp lại khối lệnh `curl` và `if` cho mỗi website, làm cho mã nguồn dài dòng và khó quản lý.
Ứng dụng mảng trong các kịch bản lập trình Bash thực tế
Sức mạnh của mảng không chỉ dừng lại ở các ví dụ đơn giản. Trong thực tế, mảng là một công cụ không thể thiếu trong rất nhiều kịch bản tự động hóa và quản trị hệ thống phức tạp. Chúng giúp xử lý dữ liệu đầu vào một cách linh hoạt, quản lý cấu hình một cách có tổ chức và thực hiện các tác vụ hàng loạt một cách hiệu quả.

Một trong những ứng dụng phổ biến nhất là tự động hóa xử lý danh sách các tệp tin. Ví dụ, bạn có thể tạo một mảng chứa tất cả các tệp có đuôi .log trong một thư mục, sau đó duyệt qua mảng này để nén từng tệp, di chuyển chúng đến một thư mục lưu trữ, hoặc phân tích nội dung của chúng. Cú pháp `files=(/var/log/*.log)` sẽ ngay lập tức tạo ra một mảng chứa đường dẫn của tất cả các tệp log, sẵn sàng cho bạn xử lý.
Tương tự, việc quản lý danh sách người dùng trên hệ thống cũng trở nên đơn giản hơn với mảng. Bạn có thể có một mảng chứa tên của những người dùng cần được tạo mới, xóa bỏ hoặc cấp quyền truy cập vào một tài nguyên nào đó. Kịch bản của bạn chỉ cần duyệt qua mảng này và thực thi các lệnh `useradd`, `userdel` hoặc `setfacl` tương ứng cho từng người dùng. Điều này giúp giảm thiểu sai sót so với việc thực hiện thủ công.
Một ứng dụng mạnh mẽ khác là quản lý cấu hình và tham số trong script. Thay vì “hard-code” (gán giá trị cố định) các tham số như địa chỉ IP, cổng, hoặc đường dẫn thư mục trực tiếp vào logic của script, bạn có thể định nghĩa chúng trong một mảng liên kết (associative array). Ví dụ: `declare -A config`, `config[db_host]=”localhost”`, `config[db_port]=”3306″`. Cách làm này giúp tách biệt phần cấu hình ra khỏi phần logic, làm cho script của bạn dễ dàng tùy chỉnh và tái sử dụng cho các môi trường khác nhau (development, staging, production) mà không cần sửa đổi mã nguồn.
Các vấn đề phổ biến và cách khắc phục
Mặc dù mảng trong Bash rất mạnh mẽ, nhưng những người mới bắt đầu thường gặp phải một số lỗi phổ biến liên quan đến cú pháp và cách xử lý dữ liệu. Hiểu rõ những vấn đề này và cách khắc phục sẽ giúp bạn tiết kiệm rất nhiều thời gian gỡ lỗi và viết kịch bản một cách tự tin hơn.

Sai cú pháp khi khai báo hoặc truy cập mảng
Một trong những lỗi phổ biến nhất là sai cú pháp khi khai báo mảng. Nhiều người quen với các ngôn ngữ lập trình khác thường dùng dấu phẩy để ngăn cách các phần tử, ví dụ: `my_array=(“a”, “b”, “c”)`. Tuy nhiên, trong Bash, các phần tử phải được ngăn cách bằng dấu cách: `my_array=(“a” “b” “c”)`. Việc dùng dấu phẩy sẽ khiến Bash hiểu toàn bộ chuỗi `”a”, “b”, “c”` là phần tử đầu tiên của mảng.
Lỗi thứ hai thường gặp là quên cặp dấu ngoặc nhọn `{}` khi truy cập phần tử. Viết `my_array[0]` thay vì `${my_array[0]}` có thể dẫn đến kết quả không mong muốn. Bash sẽ hiểu `my_array[0]` là chuỗi ký tự “my_array[0]” thay vì giá trị của phần tử đầu tiên. Luôn nhớ sử dụng cú pháp đầy đủ `${ten_mang[chi_so]}` để đảm bảo bạn đang tham chiếu chính xác đến giá trị của phần tử.
Mảng không lưu trữ đúng giá trị hoặc phần tử bị mất
Vấn đề này thường xảy ra khi các phần tử của bạn chứa dấu cách hoặc các ký tự đặc biệt, và bạn không sử dụng dấu ngoặc kép `””` một cách đúng đắn. Ví dụ, khi bạn duyệt mảng bằng `for item in ${my_array[*]}` và một phần tử có giá trị là “File Moi Cua Toi.txt”, vòng lặp sẽ xem “File”, “Moi”, “Cua”, “Toi.txt” là các phần tử riêng biệt.
Để khắc phục triệt để vấn đề này, hãy luôn tuân thủ quy tắc vàng: sử dụng dấu ngoặc kép khi tham chiếu đến toàn bộ mảng trong vòng lặp: `for item in ““${my_array[@]}”“`. Cú pháp này đảm bảo rằng mỗi phần tử của mảng, dù có chứa dấu cách hay không, đều được coi là một thực thể duy nhất và được xử lý chính xác. Tương tự, khi gán một biến chứa dấu cách vào mảng, hãy bọc nó trong dấu ngoặc kép: `my_array+=(“$ten_file”)`.

Best Practices khi làm việc với mảng trong Bash
Để viết các kịch bản Bash chuyên nghiệp, hiệu quả và dễ bảo trì, việc tuân thủ các phương pháp tốt nhất (best practices) khi làm việc với mảng là cực kỳ quan trọng. Những quy tắc này không chỉ giúp bạn tránh được các lỗi phổ biến mà còn làm cho mã nguồn của bạn trở nên rõ ràng và an toàn hơn.
Đầu tiên, hãy luôn khai báo rõ ràng kiểu mảng khi cần thiết. Mặc dù Bash thường tự động nhận diện mảng số chỉ, nhưng việc sử dụng `declare -a ten_mang` (cho mảng số chỉ) hoặc `declare -A ten_mang` (cho mảng liên kết) giúp mã nguồn của bạn trở nên minh bạch hơn. Đặc biệt, `declare -A` là bắt buộc nếu bạn muốn sử dụng mảng liên kết.

Thứ hai, luôn sử dụng dấu ngoặc kép khi mở rộng mảng để xử lý các phần tử chứa dấu cách hoặc ký tự đặc biệt một cách an toàn. Như đã đề cập, `”${ten_mang[@]}”` là người bạn đồng hành đáng tin cậy nhất của bạn. Nó đảm bảo rằng mỗi phần tử được coi là một từ riêng biệt, ngay cả khi nó chứa khoảng trắng. Ví dụ, khi truyền một mảng làm đối số cho một hàm, hãy dùng `my_function “${my_array[@]}”`.
Thứ ba, tránh sửa đổi một mảng trong khi bạn đang duyệt qua chính nó. Việc thêm hoặc xóa phần tử khỏi mảng bên trong một vòng lặp `for item in “${array[@]}”` có thể dẫn đến hành vi không đoán trước được, chẳng hạn như bỏ qua phần tử hoặc lặp vô hạn. Nếu bạn cần lọc hoặc sửa đổi mảng, một cách tiếp cận an toàn hơn là duyệt qua mảng gốc và xây dựng một mảng mới với các kết quả mong muốn.
Cuối cùng, hãy luôn kiểm tra và xác thực dữ liệu trước khi xử lý, đặc biệt là khi dữ liệu đó đến từ nguồn đầu vào của người dùng hoặc từ kết quả của một lệnh khác. Trước khi thực hiện các thao tác quan trọng, hãy kiểm tra xem mảng có rỗng hay không (`if [ ${#ten_mang[@]} -gt 0 ]`). Điều này giúp ngăn ngừa các lỗi không mong muốn và làm cho kịch bản của bạn trở nên mạnh mẽ hơn.
Kết luận
Qua bài viết này, chúng ta đã cùng nhau thực hiện một hành trình chi tiết để khám phá và làm chủ mảng trong Bash. Từ những khái niệm cơ bản nhất, cú pháp khai báo, cho đến các kỹ thuật thao tác, xử lý lỗi và ứng dụng thực tế, có thể thấy rằng mảng không chỉ là một tính năng tiện lợi mà còn là một công cụ nền tảng để xây dựng các kịch bản shell script mạnh mẽ, linh hoạt và có khả năng mở rộng.
Việc sử dụng mảng giúp bạn tổ chức dữ liệu một cách khoa học, giảm sự lặp lại mã nguồn và đơn giản hóa việc xử lý các tác vụ hàng loạt. Nó biến những kịch bản phức tạp, khó quản lý trở nên gọn gàng và dễ bảo trì hơn rất nhiều. Tầm quan trọng của nó trong tự động hóa các công việc quản trị hệ thống, xử lý dữ liệu hay triển khai ứng dụng là không thể phủ nhận.
Cách tốt nhất để thành thạo bất cứ kỹ năng nào là thông qua thực hành. Đừng ngần ngại mở trình biên dịch mã của bạn, thử nghiệm lại các ví dụ trong bài viết và tự tạo ra những kịch bản của riêng mình. Hãy bắt đầu bằng việc tự động hóa một công việc nhỏ bạn thường làm hàng ngày, chẳng hạn như sao lưu một danh sách các thư mục hoặc kiểm tra kết nối tới một loạt máy chủ. Khi bạn đã tự tin hơn, hãy tiếp tục khám phá các chủ đề nâng cao hơn như mảng đa chiều (mô phỏng bằng các kỹ thuật khác) và các thao tác phức tạp với mảng liên kết. Chúc bạn thành công trên con đường chinh phục Bash scripting!