Shell scripting là một kỹ năng thiết yếu khi làm việc với hệ điều hành Linux và Unix. Bài viết này trình bày toàn diện các khái niệm cốt lõi — từ cách tạo và thực thi script, quản lý biến, xử lý chuỗi, đến các cấu trúc điều khiển như if, for, while, until, case, cũng như cơ chế truyền tham số và chuyển hướng luồng (redirection) — tất cả đều được minh họa bằng ví dụ thực tế và giải thích rõ ràng.
Tạo và thực thi script
Để bắt đầu, tạo một tệp script đơn giản:
#!/bin/bash
echo "Chào mừng bạn đến với shell scripting!"
Lưu dưới tên welcome.sh. Để thực thi, cần cấp quyền thực thi:
chmod +x welcome.sh
./welcome.sh
Thay vì cấp quyền, bạn có thể chạy trực tiếp qua trình thông dịch:
bash welcome.sh
Mã khai báo #!/bin/bash ở dòng đầu tiên (shebang) chỉ định trình thông dịch sẽ dùng để thực thi script — khác biệt quan trọng giữa /bin/bash, /bin/sh (thường trỏ tới dash trên Debian/Kali), và /bin/dash. Trong đó, dash là phiên bản nhẹ hơn, nhanh hơn nhưng thiếu nhiều tính năng tương tác của bash.
Biến trong shell
Biến được khai báo không có dấu $, nhưng được tham chiếu kèm $:
ten="Nguyen Van A"
tuoi=28
echo "Tôi tên là $ten, năm nay $tuoi tuổi."
Phân biệt trích dẫn:
- Trích dẫn đơn (
'...'): Không thực hiện thay thế biến hay lệnh — toàn bộ nội dung được giữ nguyên. - Trích dẫn kép (
"..."): Cho phép thay thế biến ($ten) và lệnh ($(date)).
Khi nối chuỗi với biến, nên bao biến trong dấu ngoặc nhọn để tránh nhầm lẫn:
echo "Tuổi của tôi là ${tuoi} năm."
Liệt kê biến hiện tại:
set | grep ten
Xóa biến:
unset ten
Biến môi trường và đường dẫn thực thi
Các biến như $HOME, $PATH là biến môi trường toàn cục. Để thêm thư mục vào $PATH tạm thời:
export PATH="$PATH:/home/user/scripts"
Để lưu vĩnh viễn, ghi dòng trên vào tệp cấu hình shell (ví dụ: ~/.bashrc), sau đó tải lại:
source ~/.bashrc
Xử lý chuỗi
Lấy độ dài chuỗi:
chuoi="Linux Shell"
echo ${#chuoi} # Kết quả: 11
Cắt chuỗi (từ vị trí 0, lấy 5 ký tự):
echo ${chuoi:0:5} # Kết quả: Linux
Truyền tham số vào script
Các biến đặc biệt giúp truy cập đối số dòng lệnh:
$0: Tên script đang chạy.$1,$2, ...: Đối số thứ nhất, thứ hai, v.v.$#: Tổng số đối số.$@: Tất cả đối số, mỗi đối số là một chuỗi riêng biệt (khi đặt trong ngoặc kép).$*: Tất cả đối số, ghép thành một chuỗi duy nhất (phân cách bởi khoảng trắng).$?: Mã thoát của lệnh cuối cùng (0 = thành công).
Ví dụ script args.sh:
#!/bin/bash
echo "Script: $0"
echo "Số lượng đối số: $#"
echo "Tất cả đối số (dạng mảng): $@"
echo "Mã thoát trước đó: $?"
Chạy: ./args.sh "Hello World" abc 123.
Tính toán số học
Có nhiều cách thực hiện phép tính nguyên:
# Dùng cú pháp $((...))
tong=$((15 + 7))
hieu=$((tong - 5))
# Dùng let
let tich=4\*6
# Dùng expr (cần khoảng trắng xung quanh toán tử)
thuong=$(expr 20 / 4)
# Dùng bc cho phép tính dấu phẩy động
so_dong=$(echo "scale=2; 7/3" | bc)
Cấu trúc điều kiện
Câu lệnh if
#!/bin/bash
diem=85
if [ $diem -ge 90 ]; then
echo "Xuất sắc"
elif [ $diem -ge 80 ]; then
echo "Giỏi"
else
echo "Cần cải thiện"
fi
Lưu ý: Khoảng trắng xung quanh dấu ngoặc vuông và toán tử là bắt buộc.
Câu lệnh case
read -p "Nhập lựa chọn (start/stop/restart): " lua_chon
case $lua_chon in
start)
echo "Khởi động dịch vụ..."
;;
stop)
echo "Dừng dịch vụ..."
;;
restart)
echo "Khởi động lại dịch vụ..."
;;
*)
echo "Lựa chọn không hợp lệ!"
;;
esac
Vòng lặp
Vòng lặp for
# Lặp qua danh sách
for color in red green blue; do
echo "Màu: $color"
done
# Lặp qua dãy số (bash)
for i in {1..5}; do
echo "Số: $i"
done
# Cú pháp C-style (bash)
for ((i=1; i<=3; i++)); do
echo "Lần lặp: $i"
done
Vòng lặp while
count=1
while [ $count -le 3 ]; do
echo "Đếm: $count"
count=$((count + 1))
done
Vòng lặp until
num=1
until [ $num -gt 3 ]; do
echo "Giá trị: $num"
num=$((num + 1))
done
Đọc dữ liệu từ người dùng
Dùng lệnh read để tương tác:
read -p "Nhập tên: " ten
read -s -p "Nhập mật khẩu: " mat_khau # Ẩn khi nhập
echo
echo "Xin chào, $ten!"
Chuyển hướng luồng (Redirection)
> file: Ghi đè đầu ra vào file.>> file: Ghi nối đầu ra vào cuối file.< file: Đọc đầu vào từ file.2> error.log: Chuyển hướng lỗi vào file.> /dev/null 2>&1: Loại bỏ cả đầu ra và lỗi.
Ví dụ sử dụng xargs để xử lý đầu vào từ file:
# Giả sử file dirs.txt chứa các đường dẫn
cat dirs.txt | xargs ls -l
Gọi script từ script khác
Hai phương pháp chính:
- Thực thi độc lập:
bash other_script.sh— chạy trong tiến trình con, không ảnh hưởng biến cha. - Nhập (sourcing):
source other_script.shhoặc. other_script.sh— thực thi trong shell hiện tại, chia sẻ biến và hàm.
Hàm trong shell
Định nghĩa và gọi hàm:
tinh_gia_tri() {
local tong=$(( $1 + $2 ))
echo $tong
}
ket_qua=$(tinh_gia_tri 10 20)
echo "Kết quả: $ket_qua" # In ra: Kết quả: 30
Từ khóa local đảm bảo biến chỉ tồn tại trong phạm vi hàm.