Điều kiện trong Bash cho DevOps
Ở bài đầu tiên chúng ta đã viết script tuyến tính — chạy lần lượt từ trên xuống dưới. Trong thực tế vận hành, script thường phải ra quyết định: nếu service đã chạy thì bỏ qua, nếu disk vượt ngưỡng thì cảnh báo, nếu môi trường là production thì cần xác nhận trước khi deploy.
Điều kiện trong Bash chính là công cụ giúp script phản ứng linh hoạt với trạng thái hệ thống. Bài này sẽ đi qua if/elif/else, các toán tử so sánh, kiểm tra file và case…esac — kèm các ví dụ DevOps mà bạn có thể đem dùng ngay.
if / elif / else
Cú pháp cơ bản:
| |
Một vài lưu ý:
- Trong Bash hiện đại, ưu tiên dùng
[[ ... ]]thay cho[ ... ].[[ ]]là conditional expression của Bash, hỗ trợ thêm pattern matching và an toàn hơn với biến chứa khoảng trắng. - Mỗi
ifphải kết thúc bằngfi. Nếu quên,bash -n script.shsẽ báo lỗi cú pháp ngay. - Khối lệnh thường thụt vào 2 khoảng trắng để dễ đọc.
Ví dụ rất nhỏ — kiểm tra script có được chạy với quyền root hay không:
| |
EUID là biến built-in của Bash, chứa effective user ID. User root luôn có EUID=0.
Toán tử so sánh số
Khi so sánh số nguyên, dùng các toán tử dạng -eq, -ne, -gt…
| Toán tử | Ý nghĩa |
|---|---|
-eq | bằng (equal) |
-ne | khác (not equal) |
-gt | lớn hơn (greater) |
-ge | lớn hơn hoặc bằng |
-lt | nhỏ hơn (less) |
-le | nhỏ hơn hoặc bằng |
Ví dụ kiểm tra dung lượng ổ đĩa /:
| |
Script trả exit code 0/1/2 tương ứng OK/WARN/CRIT. Đây là quy ước rất quen với các hệ giám sát như Nagios/Icinga và cũng dễ dùng trong cron hoặc pipeline CI/CD.
Mẹo: Bạn có thể dùng cú pháp
(( ... ))cho số học, ví dụif (( DISK_USAGE_PERCENT >= 80 )); then. Khi nằm trong(( )), bạn không cần$trước tên biến và có thể dùng>=,<=,==quen thuộc.
Toán tử so sánh chuỗi
Với chuỗi, dùng các toán tử khác:
| Toán tử | Ý nghĩa |
|---|---|
= / == | bằng |
!= | khác |
-z STR | chuỗi rỗng |
-n STR | chuỗi không rỗng |
< / > | so sánh thứ tự (chỉ trong [[ ]]) |
Ví dụ — gate môi trường trước khi deploy:
| |
Lưu ý quan trọng: luôn quote biến ("${ENVIRONMENT}"). Nếu để $ENVIRONMENT trần và biến rỗng, biểu thức [[ $ENVIRONMENT == "production" ]] vẫn chạy được, nhưng các script tương tự với [ ... ] có thể lỗi cú pháp khi biến rỗng.
Kiểm tra file và thư mục
Bash có sẵn các toán tử dùng để kiểm tra trạng thái file:
| Toán tử | Ý nghĩa |
|---|---|
-e | tồn tại (file hoặc thư mục) |
-f | tồn tại và là file thường |
-d | tồn tại và là thư mục |
-r | đọc được |
-w | ghi được |
-x | thực thi được |
-s | file tồn tại và có kích thước > 0 |
-L | là symbolic link |
Ví dụ — script đảm bảo thư mục log tồn tại và file cấu hình hợp lệ trước khi chạy app:
| |
Dấu ! ở đầu biểu thức là phép phủ định — [[ ! -f ... ]] đọc là “nếu file không tồn tại”.
Kết hợp nhiều điều kiện (AND / OR)
Có hai cách phổ biến để ghép điều kiện:
Cách 1 — ghép trong cùng [[ ]] bằng && và ||:
| |
Cách 2 — nối hai lệnh test riêng bằng &&/|| ở mức shell:
| |
Trong script automation, cách 1 dễ đọc hơn khi điều kiện liên quan chặt với nhau. Cách 2 phù hợp khi bạn muốn “nếu lệnh này thành công thì làm tiếp”, ví dụ:
| |
Nếu mkdir thất bại, lệnh tar sẽ không chạy.
case…esac — khi if/elif quá dài
Khi cần so khớp biến với nhiều giá trị khác nhau, case thường gọn và dễ đọc hơn chuỗi if/elif.
Cú pháp:
| |
Ví dụ — script điều phối thao tác cho một service:
| |
case hỗ trợ pattern theo kiểu glob, nên bạn có thể viết dev*), *.log), [0-9]*) … rất tiện cho việc phân nhánh theo môi trường hoặc loại file.
Thực hành DevOps: check_service.sh
Ghép các kiến thức ở trên thành một script kiểm tra service và disk thực tế.
Tạo file check_service.sh:
| |
Chạy thử:
| |
Điểm đáng chú ý:
- Dùng
systemctl is-active --quietđể kiểm tra trạng thái — đây là cách “đúng chuẩn” thay vì parse output bằnggrep. - Trả exit code có ý nghĩa (
0/1/2) để cron, alertmanager hoặc pipeline CI/CD nhận biết mức độ. - Pattern
case 1 in $(( ... )) )là một kỹ thuật nhỏ: biểu thức số học trả về1khi điều kiện đúng,0khi sai — vì vậy nhánh nào “khớp” số1sẽ chạy. Nếu thấy khó đọc, bạn hoàn toàn có thể quay vềif/elif/elsecho rõ ràng.
Sai sót thường gặp
- Quên dấu cách trong
[[ ]]: Bash yêu cầu khoảng trắng quanh dấu[[,]]và quanh toán tử.[[$A == "x"]]sẽ lỗi cú pháp. - Dùng
=cho số nguyên:[[ "${COUNT}" = 1 ]]so sánh dạng chuỗi. Khi cần so sánh số, dùng-eqhoặc đưa vào(( )). - Không quote biến: Nếu biến rỗng, biểu thức có thể bị Bash phân tích sai trong
[ ](POSIX).[[ ]]an toàn hơn, nhưng vẫn nên giữ thói quen"${VAR}". - Quên
;;trongcase: Mỗi nhánhcasephải kết thúc bằng;;. Quên là Bash sẽ tiếp tục chạy sang nhánh sau khi nhánh đó match. - Lẫn lộn
&&/||với pipeline:cmd1 && cmd2chỉ chạycmd2khicmd1thành công (exit 0). Đừng nhầm với pipe|dùng để chuyển stdout.
Ghi chú triển khai
- Khi áp dụng vào dự án của bạn, hãy nghĩ về exit code trước khi viết logic: script này khi nào trả
0, khi nào trả khác0? Điều này ảnh hưởng trực tiếp tới cron và pipeline. - Best practices:
- Ưu tiên
[[ ]]thay cho[ ]trong script Bash thuần. - Luôn có nhánh
*)mặc định trongcaseđể bắt giá trị không hợp lệ và in usage. - Khi điều kiện vượt quá 4–5 nhánh
if/elif, cân nhắc chuyển sangcasehoặc tách thành function. - Đặt biến ngưỡng (threshold) lên đầu file hoặc nhận từ tham số CLI — không hardcode rải rác trong code.
- Ưu tiên
- Troubleshooting:
- Script không vào đúng nhánh? → Chạy với
bash -x script.shđể xem giá trị biến sau khi expand. - Báo lỗi
unary operator expected? → Thường do biến rỗng trong[ -f $FILE ]. Đổi sang[[ -f "${FILE}" ]]. casekhông match? → Kiểm tra pattern có cần quote không. Trongcase, phía bên phảiinlà pattern (glob), không phải chuỗi đơn thuần.
- Script không vào đúng nhánh? → Chạy với
🎯 Lời kết
Điều kiện là bước đầu tiên giúp script Bash của bạn “có não” — biết phản ứng theo trạng thái thay vì chạy mù. Với if/elif/else, case…esac, các toán tử so sánh số, chuỗi và kiểm tra file, bạn đã đủ công cụ để viết những script vận hành thực tế như healthcheck, gate deploy, hay điều phối service.
Ở bài tiếp theo, chúng ta sẽ đi vào vòng lặp trong Bash với for, while, until, kèm các ví dụ tự động hoá lặp qua danh sách server và đọc file log theo dòng. 🚀
Tài liệu tham khảo
- GNU Bash Manual — Conditional Constructs — Tài liệu chính thức về
if,case,select. - GNU Bash Manual — Bash Conditional Expressions — Đầy đủ các toán tử file, chuỗi, số dùng trong
[[ ]]vàtest. - GNU Bash Manual — Shell Arithmetic — Cú pháp
(( ... ))cho biểu thức số học. - ShellCheck — Công cụ lint giúp phát hiện các lỗi quote, so sánh sai kiểu trước khi đưa script vào production.
