Featured image of post Cơ bản Bash Script trong DevOps

Cơ bản Bash Script trong DevOps

Làm quen với Bash Script từ nền tảng: Bash là gì, cách viết script đầu tiên, sử dụng biến, lệnh cơ bản, debug và thực hành kiểm tra thông tin hệ thống cho DevOps.

Cơ bản Bash Script trong DevOps

Trong công việc DevOps, có rất nhiều tác vụ lặp lại hằng ngày: kiểm tra dung lượng ổ đĩa, xem service còn chạy không, backup file cấu hình, gom log, hoặc chạy một chuỗi lệnh deploy đơn giản. Nếu làm thủ công từng bước, bạn rất dễ quên lệnh, gõ sai tham số hoặc mất thời gian khi phải thao tác trên nhiều server.

Bash Script giúp đóng gói các lệnh đó thành một file có thể chạy lại nhiều lần. Đây là kỹ năng nền tảng trước khi bạn đi sâu vào CI/CD, Docker, Kubernetes, Cloud CLI hay automation phức tạp hơn.


Bash là gì?

Bash là viết tắt của Bourne Again SHell — một chương trình shell phổ biến trên Linux và macOS. Shell nhận lệnh từ người dùng, diễn giải lệnh đó, rồi yêu cầu hệ điều hành thực thi.

Khi bạn gõ lệnh trong terminal như:

1
2
3
ls -lah
df -h
cat /etc/os-release

bạn đang tương tác với shell. Khi gom nhiều lệnh vào một file text, file đó trở thành shell script. Theo tài liệu chính thức của GNU Bash, một shell script là file văn bản chứa các lệnh shell; khi được Bash chạy, Bash đọc và thực thi các lệnh trong file đó rồi thoát.


Vì sao DevOps cần biết Bash?

Bash không thay thế các công cụ như Ansible, Terraform hay Jenkins, nhưng nó là lớp keo rất hữu ích để nối các công cụ lại với nhau.

Tình huống DevOpsBash giúp gì?
Kiểm tra server nhanhGom hostname, df, free, uptime vào một script
Deploy ứng dụng nhỏChạy pull code, build, restart service theo đúng thứ tự
Dọn log hoặc file tạmTự động tìm và xoá file cũ theo lịch
CI/CD pipelineViết step build/test/deploy có exit code rõ ràng
Tích hợp toolGọi docker, kubectl, aws, curl, jq từ một script

Điểm mạnh của Bash là có sẵn trên hầu hết server Linux, không cần cài runtime phức tạp. Với những tác vụ nhỏ, một script 20–50 dòng thường đủ nhanh, dễ đọc và dễ đưa vào pipeline.


Script đầu tiên với hello.sh

Tạo file hello.sh:

1
vi hello.sh

Thêm nội dung sau:

1
2
3
4
#!/usr/bin/env bash

echo "Hello DevOps!"
echo "Script đang chạy trên máy: $(hostname)"

Chạy script bằng Bash:

1
bash hello.sh

Hoặc cấp quyền thực thi rồi chạy trực tiếp:

1
2
chmod +x hello.sh
./hello.sh

Shebang dùng để làm gì?

Dòng đầu tiên:

1
#!/usr/bin/env bash

được gọi là shebang. Nó cho hệ điều hành biết nên dùng chương trình nào để chạy file này. Cách viết #!/usr/bin/env bash thường linh hoạt hơn #!/bin/bash vì Bash có thể nằm ở vị trí khác nhau tuỳ hệ thống.


Làm việc với biến

Biến giúp script lưu giá trị để tái sử dụng. Cú pháp gán biến trong Bash không có khoảng trắng quanh dấu =:

1
2
3
4
5
APP_NAME="manager-blog"
ENVIRONMENT="staging"

echo "Ứng dụng: $APP_NAME"
echo "Môi trường: ${ENVIRONMENT}"

Nên dùng ${VAR} khi ghép biến với chuỗi để tránh Bash hiểu nhầm tên biến:

1
2
3
4
BACKUP_DIR="/backup"
APP_NAME="manager-blog"

echo "File backup: ${BACKUP_DIR}/${APP_NAME}.tar.gz"

Một số biến đặc biệt hay gặp

BiếnÝ nghĩa
$0Tên script đang chạy
$1Tham số đầu tiên truyền vào script
$#Tổng số tham số
$?Exit code của lệnh vừa chạy
$$Process ID của shell hiện tại

Ví dụ script nhận tên môi trường:

1
2
3
4
5
#!/usr/bin/env bash

ENVIRONMENT="${1:-dev}"

echo "Deploy tới môi trường: ${ENVIRONMENT}"

Chạy thử:

1
bash deploy-message.sh staging

Nếu không truyền tham số, ${1:-dev} sẽ dùng giá trị mặc định là dev.


Một số lệnh cơ bản thường dùng

echo

echo in nội dung ra màn hình, rất hữu ích để hiển thị trạng thái trong script:

1
2
echo "Bắt đầu kiểm tra hệ thống..."
echo "Hoàn tất."

read

read đọc input từ người dùng:

1
2
3
4
#!/usr/bin/env bash

read -r -p "Nhập tên service cần kiểm tra: " SERVICE_NAME
echo "Bạn muốn kiểm tra service: ${SERVICE_NAME}"

Trong script, nên dùng read -r để tránh việc dấu backslash bị diễn giải ngoài ý muốn.

cat

cat thường dùng để xem nhanh nội dung file hoặc tạo file mẫu:

1
cat /etc/os-release

Tạo file cấu hình bằng here-document:

1
2
3
4
cat > app.env <<'EOF'
APP_ENV=staging
APP_PORT=8080
EOF

ls

ls liệt kê file/thư mục:

1
ls -lah /var/log

Trong script production, nếu cần xử lý danh sách file phức tạp, bạn nên cẩn thận với tên file có khoảng trắng. Các bài sau về xử lý file sẽ đi sâu hơn vào chủ đề này.


Thực hành DevOps: check_system.sh

Ví dụ dưới đây tạo một script kiểm tra nhanh thông tin hệ thống: hostname, hệ điều hành, uptime, CPU load, RAM và dung lượng ổ đĩa root.

Tạo file:

1
vi check_system.sh

Nội dung script:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#!/usr/bin/env bash
set -euo pipefail

echo "========================================"
echo "  System quick check"
echo "========================================"

HOSTNAME_VALUE="$(hostname)"
KERNEL_VALUE="$(uname -sr)"
UPTIME_VALUE="$(uptime -p 2>/dev/null || uptime)"
DISK_USAGE_PERCENT="$(df -P / | awk 'NR==2 {gsub("%", "", $5); print $5}')"

if [[ -r /proc/loadavg ]]; then
  LOAD_1M="$(awk '{print $1}' /proc/loadavg)"
else
  LOAD_1M="$(uptime | awk -F'load average: ' '{print $2}' | awk -F',' '{print $1}')"
fi

echo "Hostname : ${HOSTNAME_VALUE}"
echo "Kernel   : ${KERNEL_VALUE}"
echo "Uptime   : ${UPTIME_VALUE}"
echo "Load 1m  : ${LOAD_1M}"
echo "Disk /   : ${DISK_USAGE_PERCENT}%"

if command -v free >/dev/null 2>&1; then
  echo
  echo "Memory:"
  free -h
else
  echo
  echo "Memory: command 'free' không có trên hệ thống này."
fi

echo
if (( DISK_USAGE_PERCENT >= 80 )); then
  echo "WARNING: Dung lượng ổ đĩa / đã vượt ngưỡng 80%."
  exit 1
else
  echo "OK: Dung lượng ổ đĩa / vẫn trong ngưỡng an toàn."
fi

Cấp quyền và chạy:

1
2
chmod +x check_system.sh
./check_system.sh

Output có thể tương tự:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
========================================
  System quick check
========================================
Hostname : webserver-01
Kernel   : Linux 6.8.0-31-generic
Uptime   : up 3 days, 4 hours, 12 minutes
Load 1m  : 0.21
Disk /   : 42%

Memory:
               total        used        free      shared  buff/cache   available
Mem:           3.8Gi       1.1Gi       720Mi        32Mi       2.0Gi       2.4Gi
Swap:          2.0Gi          0B       2.0Gi

OK: Dung lượng ổ đĩa / vẫn trong ngưỡng an toàn.

Điểm đáng chú ý trong script:

  • set -euo pipefail giúp script dừng khi gặp lỗi, khi dùng biến chưa khai báo, hoặc khi một lệnh trong pipeline bị lỗi.
  • df -P / dùng định dạng POSIX để output ổn định hơn khi parse bằng awk.
  • command -v free kiểm tra lệnh free có tồn tại trước khi gọi.
  • exit 1 khi disk vượt ngưỡng giúp CI/CD hoặc cron job nhận biết script đang báo lỗi.

Debug script với bash -n và bash -x

Khi script dài hơn, bạn cần kiểm tra lỗi cú pháp và xem Bash thực thi từng lệnh như thế nào.

Kiểm tra cú pháp với bash -n

1
bash -n check_system.sh

Tuỳ chọn -n yêu cầu Bash đọc lệnh nhưng không thực thi. Nó hữu ích để phát hiện lỗi như thiếu fi, thiếu dấu nháy, hoặc sai cú pháp vòng lặp.

Trace từng lệnh với bash -x

1
bash -x check_system.sh

Tuỳ chọn -x in ra từng lệnh sau khi Bash đã expand biến và trước khi thực thi. Đây là cách rất nhanh để biết script đang nhận giá trị nào.

Bạn cũng có thể bật/tắt trace trong một đoạn cụ thể:

1
2
3
set -x
DISK_USAGE_PERCENT="$(df -P / | awk 'NR==2 {gsub("%", "", $5); print $5}')"
set +x

Lưu ý bảo mật: Không bật set -x quanh đoạn xử lý secret/token vì giá trị nhạy cảm có thể bị in ra log.


Best practice khi mới viết Bash

Một vài thói quen nhỏ sẽ giúp script dễ đọc và ít lỗi hơn:

  • Luôn quote biến: dùng "${VAR}" thay vì $VAR, đặc biệt khi giá trị có khoảng trắng.
  • Đặt tên biến rõ nghĩa: DISK_USAGE_PERCENT dễ hiểu hơn D hoặc VALUE.
  • Dùng set -euo pipefail có chủ đích: tốt cho nhiều script automation, nhưng cần hiểu luồng lỗi trước khi dùng trong script phức tạp.
  • Kiểm tra command trước khi dùng: command -v docker, command -v jq, command -v kubectl.
  • Không hardcode thông tin nhạy cảm: token, password, private key nên lấy từ environment variable hoặc secret manager.
  • Trả exit code rõ ràng: exit 0 cho thành công, khác 0 cho lỗi để cron/CI/CD nhận biết.
  • Chạy bash -n trước khi deploy: đây là bước kiểm tra nhanh nhưng rất hữu ích.

Ghi chú triển khai

  • Khi áp dụng vào dự án của bạn, hãy bắt đầu bằng các script nhỏ, rõ mục tiêu: check_system.sh, backup_config.sh, restart_service.sh. Đừng cố viết một script quá lớn ngay từ đầu.
  • Best practices:
    • Đặt script trong thư mục riêng như scripts/ hoặc ops/.
    • Thêm README ngắn mô tả cách chạy, tham số đầu vào và ví dụ output.
    • Với script chạy trong CI/CD, luôn kiểm tra exit code và log đủ thông tin để debug.
  • Troubleshooting:
    • Lỗi Permission denied? → Chạy chmod +x script.sh hoặc dùng bash script.sh.
    • Lỗi command not found? → Kiểm tra command đã cài chưa và biến PATH có đúng không.
    • Script chạy khác giữa local và server? → Kiểm tra phiên bản Bash bằng bash --version và hệ điều hành bằng cat /etc/os-release.

🎯 Lời kết

Bash Script là kỹ năng nền tảng nhưng rất thực dụng trong DevOps. Chỉ với vài lệnh cơ bản như echo, read, cat, ls, kết hợp biến và kiểm tra exit code, bạn đã có thể tự động hóa nhiều tác vụ vận hành hằng ngày.

Ở bài tiếp theo, chúng ta sẽ đi vào điều kiện trong Bash với if/elif/else, toán tử so sánh, kiểm tra file và case...esac — những thành phần giúp script bắt đầu có logic xử lý linh hoạt hơn. 🚀


Tài liệu tham khảo