Giới thiệu
Trong phần 4 của hành trình DevOps, tôi đã thiết lập cronjob, nhưng tôi nhận ra rằng việc gõ lệnh thủ công không hiệu quả. Trong thế giới thực, hệ thống không chờ bạn gõ lệnh — chúng gặp sự cố khi bạn đang ngủ. Đó là lúc tôi bắt đầu sử dụng Shell Scripting.
Thay vì học theo cách truyền thống, tôi đã học qua những tình huống khắc phục sự cố thực tế. Mỗi khái niệm — biến, tham số, vòng lặp — trở nên sống động chỉ khi tôi đối mặt với vấn đề cần giải quyết.
Dưới đây là cách mà scripting trở thành công cụ cứu cánh của tôi trong thực tế.
1️⃣ Viết Script Đầu Tiên — Cơn Ác Mộng Lặp Đi Lặp Lại
Tình huống: Trong thời gian thực tập, tôi thường nhận được cảnh báo đĩa đầy vào giữa đêm. Mỗi lần như vậy, tôi phải đăng nhập và gõ lệnh df -h thủ công. Thật mệt mỏi.
Giải pháp:
Tôi đã viết một script gọi là diskcheck.sh:
bash
#!/bin/bash
df -h
Bây giờ, thay vì gõ lệnh trong trạng thái nửa tỉnh nửa mơ, tôi chỉ cần chạy:
bash
./diskcheck.sh
👉 Bài học: Scripts là bộ não thứ hai của bạn trong thời gian trực.
2️⃣ Biến — Thách Thức “Nhiều Máy Chủ, Một Script”
Tình huống: Tôi cần kiểm tra kết nối cho 3 máy chủ khác nhau. Script đầu tiên của tôi đã cố định IP. Nếu máy chủ thay đổi, script sẽ hỏng.
Giải pháp:
Sử dụng biến:
bash
# Thiết lập biến cho địa chỉ IP
SERVER_IP=$1
ping -c 4 $SERVER_IP
Sau đó, tôi chỉ cần thay đổi giá trị và script hoạt động ở mọi nơi.
👉 Bài học: Biến giúp script không trở nên vô dụng khi hạ tầng thay đổi.
3️⃣ Toán Tử — Vấn Đề “Cảnh Báo Đĩa Đầy”
Tình huống: Một máy chủ staging hết dung lượng, khiến ứng dụng bị sập. Tôi cần một script kiểm tra dung lượng đĩa và chỉ cảnh báo khi vượt quá 80%.
Giải pháp:
bash
USED=$(df / | grep / | awk '{ print $5 }' | sed 's/%//g')
THRESHOLD=80
if [ $USED -gt $THRESHOLD ]; then
echo "Dung lượng đĩa ở mức báo động: $USED%"
fi
👉 Bài học: Toán tử + điều kiện = giám sát tự động mà không cần công cụ bên ngoài.
4️⃣ Đọc Dữ Liệu Người Dùng — Vấn Đề “Linh Hoạt Sao Lưu”
Tình huống: Script sao lưu của tôi chỉ lưu trữ thư mục /home/, nhưng đôi khi tôi cũng cần sao lưu cấu hình từ /etc/. Việc chỉnh sửa script mỗi lần thật bất tiện.
Giải pháp: Để script hỏi:
bash
echo "Nhập đường dẫn để sao lưu:"
read PATH
tar -cvf backup.tar $PATH
Bây giờ tôi có thể chạy nó cho bất kỳ thư mục nào.
👉 Bài học: Tính tương tác giúp script linh hoạt hơn trong môi trường khác nhau.
5️⃣ Hàm — Vấn Đề “Mess Log Rải Rác”
Tình huống: Tôi có nhiều script xuất log với định dạng ngẫu nhiên. Việc gỡ lỗi các lỗi trở nên cực kỳ khó khăn.
Giải pháp: Tôi tạo một hàm ghi log tái sử dụng:
bash
log() {
echo "[INFO] $(date): $1"
}
log "Sao lưu bắt đầu"
log "Sao lưu hoàn thành"
Bây giờ tất cả các script của tôi đều nói chung một ngôn ngữ.
👉 Bài học: Hàm mang lại tính nhất quán cho tự động hóa lộn xộn.
6️⃣ Shell vs sh vs Bash — Vấn Đề “Chạy trên Ubuntu, Lỗi trên Alpine”
Tình huống: Một script triển khai chạy tốt trên Ubuntu nhưng lại thất bại trong container Docker nhẹ Alpine.
Vấn đề: Alpine sử dụng /bin/sh, không hỗ trợ một số tính năng của Bash.
Giải pháp: Luôn chỉ định thông dịch viên:
bash
#!/bin/bash
👉 Bài học: Rõ ràng thì tốt hơn ngầm hiểu. Luôn xác định shell của bạn.
7️⃣ Điều Kiện — Thảm Họa “Đừng Xóa Khi Đang Chạy”
Tình huống: Một script dọn dẹp bắt đầu xóa log trong khi nginx vẫn đang chạy. Dịch vụ đã sập.
Giải pháp: Thêm kiểm tra an toàn:
bash
if pgrep nginx; then
echo "Nginx đang chạy. Bỏ qua dọn dẹp."
else
rm -rf /var/log/nginx/*
fi
👉 Bài học: Điều kiện là hàng rào bảo vệ giúp tự động hóa an toàn.
8️⃣ Tham Số — Vấn Đề “Một Script Cho Mỗi Môi Trường”
Tình huống: Tôi có các script riêng biệt cho sao lưu dev, test và prod. Không thể quản lý nổi.
Giải pháp:
bash
ENV=$1
echo "Đang sao lưu môi trường $ENV..."
tar -cvf backup_$ENV.tar /var/$ENV/
Chạy với:
bash
./backup.sh dev
./backup.sh prod
👉 Bài học: Tham số giúp script có thể mở rộng cho nhiều môi trường khác nhau.
9️⃣ Vòng Lặp — Vấn Đề “50 Tệp Log”
Tình huống: Nén các log một cách tuần tự? Không thể trong lúc xảy ra sự cố.
Giải pháp:
bash
for file in /var/log/*.log; do
gzip $file
done
👉 Bài học: Vòng lặp là cứu cánh thời gian cho các thao tác hàng loạt.
🎭 Điểm Chuyển Biến Nâng Cao: Khi Script của Tôi Suýt Xóa Production
Một đêm muộn, tôi được yêu cầu “dọn dẹp các tệp tạm”. Tôi đã viết một cách vội vàng:
- Nhưng tôi quên rằng script đang chạy với quyền root bên trong một container mount. Nó bắt đầu xóa các tệp chia sẻ quan trọng.
- Tôi đã dừng lại bằng Ctrl+C, nhưng thiệt hại đã xảy ra — một số cấu hình đã bị mất.
Cách tôi phục hồi:
- Khôi phục cấu hình từ bản sao lưu.
- Thêm tính năng dry-run cho các script của tôi:
bash
echo "Sẽ xóa: $file"
- trước khi thực sự chạy
rm. - Thực hiện
set -evà ghi log cho tất cả các script quan trọng.
👉 Bài học: Scripts giống như dao mổ — mạnh mẽ, chính xác và nguy hiểm. Hãy đối xử chúng với sự tôn trọng.
🌟 Những Điều Rút Ra Chính từ Phần 5
- Các khái niệm về shell scripting chỉ thực sự sống động qua những vấn đề thực tế.
- Biến, tham số, vòng lặp → không phải chỉ là “cú pháp”, mà là giải pháp cho những khó khăn trong DevOps.
- Các điều kiện và hàm ngăn chặn thảm họa.
- Luôn thử nghiệm trong môi trường thử nghiệm trước khi chuyển sang sản xuất.
- Scripts không phải là đồ chơi — chúng là dây chuyền sống của hệ thống.
🚀 Những Gì Tiếp Theo (Phần 6: Cơ Bản Về Mạng)
Bây giờ tôi có thể scripting để giải quyết vấn đề, bước tiếp theo là đảm bảo hệ thống có thể giao tiếp với nhau.
Trong phần 6, tôi sẽ khám phá:
- Tổng quan về Mạng Máy Tính
- Mô hình OSI
- LAN, Switch, Router, Subnet, Firewall
- Mạng Đám Mây
- Mạng Microservices
🤝 Đến lượt bạn
Thảm họa shell scripting lớn nhất của bạn là gì? Bạn đã bao giờ chạy lệnh nào khiến bạn toát mồ hôi? Hãy chia sẻ ở dưới — có thể chúng ta sẽ cứu ai đó khỏi việc lặp lại nó.