hoatranlab.io.vn Zalo: 0917516878 Hotline: 0917516878 [email protected]
HoaTranLab Logo HoaTranLab
Linux Bible 11th Edition • Chapter 7

Writing Simple Shell Scripts

Master Bash scripting: variables, conditionals, loops, functions, and special parameters — automate repetitive Linux administration tasks effectively.

Mục tiêu chương

Sau khi hoàn thành chương này, bạn sẽ có thể:

Tạo và chạy Script

Viết và thực thi shell script với shebang #!/bin/bash, set quyền execute với chmod +x.

Biến và tham số

Khai báo và sử dụng biến, tham số vị trí ($1, $2, $@), biến đặc biệt ($?, $$, $#).

Tính toán số học

Thực hiện phép tính số nguyên bằng let, expr, bc và cú pháp $(( )).

Lệnh điều kiện

Viết câu lệnh if/then/else/fi, case/esac để xử lý logic phân nhánh.

Vòng lặp

Sử dụng vòng lặp for, while, until để lặp lại các tác vụ xử lý danh sách và điều kiện.

grep, sed, awk, cut

Kết hợp các công cụ xử lý văn bản mạnh mẽ trong script để phân tích dữ liệu.

Lý thuyết chi tiết

Các khái niệm và cú pháp Shell Script trong chương 7

Cơ bản về Shell Script

Shell script là tệp tin văn bản chứa các lệnh Bash. Có hai cách chạy: dùng bash myscript hoặc thêm shebang #!/bin/bash và cấp quyền execute. Script có thể chứa biến, hàm, vòng lặp, điều kiện.

myscript.sh

#!/bin/bash

# Script to display system info

echo

"Hello, $USER!"

echo

"Today is: $(date)"

echo

"Hostname: $(hostname)"

$ chmod +x myscript.sh

$ ./myscript.sh

Hello, chris!

Today is: Mon Jul 27 11:20:26 AM EDT 2025

Hostname: fedora-ws

# Debug mode: hien thi tung lenh truoc khi chay

$ bash -x myscript.sh

Biến (Variables) trong Shell Script

Biến trong Bash phân biệt chữ hoa/thường. Gán giá trị: NAME=value (không có khoảng trắng). Truy xuất: $NAME hoặc ${NAME}. Lưu output lệnh: VAR=$(command).

Terminal

CITY="Springfield"

PI=3.14159265

MYDATE=$(date)

MACHINE=`uname -n`

NUM_FILES=$(/bin/ls | wc -l)

$ echo "City: $CITY, Files: $NUM_FILES"

City: Springfield, Files: 42

# Parameter expansion

MYFILENAME=/home/digby/myfile.txt

FILE=${MYFILENAME##*/} # myfile.txt

DIR=${MYFILENAME%/*} # /home/digby

NAME=${FILE%.*} # myfile

EXT=${FILE##*.} # txt

Biến đặc biệt (Special Variables)

  • $0 — Tên script/lệnh
  • $1, $2... — Tham số dòng lệnh
  • $# — Số lượng tham số
  • $@ — Tất cả tham số
  • $? — Exit code lệnh vừa chạy
  • $$ — PID của shell hiện tại

Lệnh read — Nhập tương tác

#!/bin/bash

read -p "Enter name: " USERNAME

echo "Hello, $USERNAME!"

$ ./script.sh

Enter name: Chris

Hello, Chris!

Tính toán số học trong Script

Bash xử lý biến như chuỗi ký tự. Để tính toán số học, dùng let, expr, bc hoặc cú pháp $(( )).

Terminal

BIGNUM=1024

let RESULT=$BIGNUM/16 # RESULT=64

RESULT=`expr $BIGNUM / 16` # RESULT=64

RESULT=`echo "$BIGNUM / 16" | bc` # RESULT=64

# Cu phap $(( )) voi increment

$ I=0

$ echo "After increment: $((++I))"

After increment: 1

$ echo "Before/After: $((I++)) and $I"

Before/After: 1 and 2

# Random number 0-10

$ let foo=$RANDOM%11; echo $foo

7

Câu lệnh điều kiện (if/case)

Cú pháp if trong Bash: if [ condition ]; then ... elif ...; else ...; fi. Dùng -eq, -ne, -lt, -gt cho số; -z, -n, =, != cho chuỗi; -f, -d, -e cho file.

check_score.sh

#!/bin/bash

SCORE=$1

if

[ $SCORE -ge 90 ]; then

echo "Excellent: A"

elif

[ $SCORE -ge 70 ]; then

echo "Good: B"

else

echo "Need improvement: C"

fi

$ ./check_score.sh 85

Good: B

# Kiem tra file ton tai

if

[ -f /etc/passwd ]; then echo "File exists"; fi

case_example.sh

#!/bin/bash

# case/esac for multiple conditions

case

$1 in

start) echo "Starting service..." ;;

stop) echo "Stopping service..." ;;

restart) echo "Restarting service..." ;;

*) echo "Usage: $0 {start|stop|restart}" ;;

esac

$ ./service.sh start

Starting service...

Vòng lặp (for, while, until)

Ba loại vòng lặp chính trong Bash: for lặp qua danh sách; while chạy khi điều kiện đúng; until chạy khi điều kiện sai.

loops.sh

#!/bin/bash

# for loop - lap qua danh sach

for

FRUIT in apple banana cherry; do

echo "Fruit: $FRUIT"

done

Fruit: apple

Fruit: banana

Fruit: cherry

# for loop - lap so

for

i in $(seq 1 5); do echo "Count: $i"; done

# while loop

COUNT=1

while

[ $COUNT -le 3 ]; do

echo "Count: $COUNT"

COUNT=$((COUNT+1))

done

# for loop over files

for

FILE in /etc/*.conf; do

echo "Config: $FILE"

done

Công cụ xử lý văn bản: grep, sed, awk, cut

Các công cụ này rất quan trọng trong shell script để tìm kiếm, lọc, biến đổi và phân tích dữ liệu văn bản.

grep — Tìm kiếm mẫu

$ grep "root" /etc/passwd

root:x:0:0:root:/root:/bin/bash

$ grep -i "error" /var/log/syslog

$ grep -r "TODO" /home/chris/scripts/

$ grep -c "failed" auth.log

23

sed — Stream Editor

$ sed 's/old/new/g' file.txt

$ sed -i 's/foo/bar/g' file.txt

$ sed -n '5,10p' file.txt

$ sed '/^#/d' config.txt

# Xoa dong bat dau bang #

awk — Xử lý cột

$ awk '{print $1}' /etc/passwd

$ awk -F: '{print $1,$3}' /etc/passwd

root 0

daemon 1

$ awk '{sum+=$3} END {print sum}' data.txt

cut — Cắt cột

$ cut -d: -f1 /etc/passwd

root, daemon, bin...

$ cut -d, -f2 data.csv

$ echo "hello world" | cut -c1-5

hello

Bài Lab Thực Hành

Viết Shell Script từ đơn giản đến phức tạp

1

Script hiển thị thông tin hệ thống

Tạo script đầu tiên với shebang, comments và biến.

sysinfo.sh

#!/bin/bash

# System Information Script

HOSTNAME=$(hostname)

KERNEL=$(uname -r)

UPTIME=$(uptime -p)

USERS=$(who | wc -l)

echo "=== System Info ==="

echo "Host: $HOSTNAME"

echo "Kernel: $KERNEL"

echo "Uptime: $UPTIME"

echo "Users logged in: $USERS"

$ chmod +x sysinfo.sh && ./sysinfo.sh

=== System Info ===

Host: fedora-ws

Kernel: 6.11.4-301.fc41.x86_64

Uptime: up 2 hours, 15 minutes

Users logged in: 2

2

Script với tham số dòng lệnh

Tạo script sử dụng $1, $2, $# để nhận tham số.

greet.sh

#!/bin/bash

echo "Script: $0"

echo "First arg: $1, Second: $2"

echo "Total args: $#"

echo "All args: $@"

$ chmod 755 /home/chris/bin/greet.sh

$ greet.sh foo bar

Script: /home/chris/bin/greet.sh

First arg: foo, Second: bar

Total args: 2

All args: foo bar

3

Script kiểm tra file và thư mục

Dùng if/then/else để kiểm tra sự tồn tại của file.

check_file.sh

#!/bin/bash

FILE=$1

if

[ -z "$FILE" ]; then

echo "Usage: $0 filename"; exit 1

elif

[ -f "$FILE" ]; then

echo "$FILE is a regular file"

elif

[ -d "$FILE" ]; then

echo "$FILE is a directory"

else

echo "$FILE does not exist"

fi

$ ./check_file.sh /etc/passwd

/etc/passwd is a regular file

4

Script backup tự động với vòng lặp

Tạo script backup nhiều thư mục bằng vòng lặp for.

backup.sh

#!/bin/bash

BACKUP_DIR="/tmp/backup_$(date +%Y%m%d)"

mkdir -p "$BACKUP_DIR"

for

DIR in /etc /home /var/log; do

if

[ -d "$DIR" ]; then

tar czf "$BACKUP_DIR/$(basename $DIR).tar.gz" "$DIR"

echo "Backed up: $DIR"

fi

done

echo "Backup complete: $BACKUP_DIR"

$ ./backup.sh

Backed up: /etc

Backed up: /home

Backup complete: /tmp/backup_20251027

5

Xử lý văn bản với grep và awk

Phân tích /etc/passwd để lạy thông tin user.

Terminal

$ grep "^chris" /etc/passwd

chris:x:1000:1000:Chris Smith:/home/chris:/bin/bash

$ awk -F: '$3 >= 1000 {print $1, $6}' /etc/passwd

chris /home/chris

alice /home/alice

$ cut -d: -f1,3 /etc/passwd | grep ":[0-9]*$"

root:0

daemon:1

$ cat /etc/passwd | sed 's/\/bin\/bash/\/bin\/sh/g'

# Thay doi shell tu bash sang sh (chi hien thi)

6

Script kiểm tra dịch vụ và restart nếu cần

Tạo script thực tế để kiểm tra và tự động restart service.

check_service.sh

#!/bin/bash

SERVICE="httpd"

if

systemctl is-active --quiet "$SERVICE"; then

echo "$SERVICE is running OK"

else

echo "$SERVICE is DOWN! Restarting..."

systemctl restart "$SERVICE"

if

[ $? -eq 0 ]; then

echo "$SERVICE restarted successfully"

else

echo "FAILED to restart $SERVICE!"

fi

fi

$ sudo ./check_service.sh

httpd is DOWN! Restarting...

httpd restarted successfully

Câu hỏi Ôn tập

Kiểm tra kiến thức Chapter 7

1

Shebang #!/bin/bash có vai trò gì trong shell script?

Shebang cho hệ điều hành biết dùng trình thông dịch nào để chạy script. #!/bin/bash cho kernel biết dùng Bash. Shebang luôn phải ở dòng đầu tiên. Không có shebang, script vẫn chạy được nhưng có thể dùng shell hiện tại thay vì bash.

2

Biến $? cho biết điều gì?

$? là exit code của lệnh vừa chạy xong. Giá trị 0 = thành công. Giá trị khác 0 = lỗi. Ví dụ: sau khi chạy cp file1 file2, kiểm tra if [ $? -eq 0 ]; then echo OK; fi.

3

Sự khác nhau giữa $@ và $* khi đặt trong dấu ngoặc kép?

"$@" mở rộng mỗi tham số thành chuỗi riêng biệt (giữ nguyên tất cả dấu cách). "$*" gộp tất cả tham số thành một chuỗi đơn. Trong for loop, nên dùng "$@" để xử lý đúng tham số có dấu cách.

4

Viết vòng lặp in số từ 1 đến 10 chỉ dùng while.

i=1; while [ $i -le 10 ]; do echo $i; i=$((i+1)); done

Hoặc: for i in $(seq 1 10); do echo $i; done

5

Lệnh grep -v làm gì? Cho ví dụ thực tế.

$ grep -v "^#" /etc/sshd_config

grep -v loại bỏ các dòng khớp với mẫu. Ví dụ trên hiển thị tất cả dòng không phải comment (không bắt đầu bằng #) trong file cấu hình SSH.

6

Cú pháp để gán output của lệnh vào biến là gì?

VAR=$(command) # Cu phap hien dai
VAR=`command` # Cu phap cu (backticks)

Ví dụ: HOSTNAME=$(hostname), DATE=$(date +%Y%m%d). Cú pháp $() có thể lồng nhau được, backticks thì không.

7

Lệnh sed để thay thế tất cả "foo" bằng "bar" trong file là gì?

$ sed -i 's/foo/bar/g' file.txt

Cờ -i sửa thẳng file (in-place). S mỡu s/pattern/replacement/g: g=global thay tất cả. Không có g sẽ chỉ thay từng xuất hiện đầu tiên trên mỗi dòng.

8

Debug shell script bằng cách nào?

$ bash -x myscript.sh
# Hoặc them dong nay vao script:
set -x # bat debug mode

bash -x in ra từng lệnh trước khi thực hiện (prefix bằng +). Giúp theo dõi luồng chạy và phát hiện lỗi. Còn có thể dùng echo để in giá trị biến tại các điểm kiểm tra.