Bash là một scripting language hoạt động trên đa số các distro của Linux và MacOS. Bash script là một chuỗi các bash command ở trong một file.

Our First Simple Bash Scripts

Một bash script luôn bắt đầu bằng dòng sau:

#!/bin/bash

Dòng này là để cho hệ điều hành biết interpreter dùng để chạy script.

Chương trình Hello World ở trong bash script:

#!/bin/bash
 
echo "Hello World!"

Lệnh echo sẽ in chuỗi "Hello World!" ra terminal.

Thêm quyền thực thi cho file:

chmod +x bash.sh

Thực thi:

 ./bash.sh
Hello World!

Variables

Khởi tạo biến trong bash script tương tự như biến trong Python:

name="insomnia"

Thêm vào ký tự $ ở trước tên biến để sử dụng biến:

name="insomnia"
echo $name

Chúng ta cũng có thể dùng nhiều biến cho lệnh echo như sau:

name="insomnia"
age=22
 
echo "$name is $age years old"

Debugging

Debug một bash script bằng cách dùng lệnh sau:

 bash -x ./file.sh

Nếu chúng ta muốn debug một đoạn nhất định thì có thể bọc đoạn code đó bằng set -xset +x như sau:

echo "hi"
 
set -x
# this section will be debugged
set +x

Ví dụ, xét bash script sau:

echo "Hello World!"
 
whoami
 
ls

Khi chạy debug thì output sẽ là:

 bash -x ./bash.sh
+ echo 'Hello World!'
Hello World!
+ whoami
aleister
+ ls
bash.sh

Có thể thấy, kết quả của từng câu lệnh được đặt ngay bên dưới câu lệnh đó.

Trường hợp xảy ra lỗi:

 bash -x ./bash.sh
+ sl
./bash.sh: line 2: sl: command not found

Parameters

Các đối số dòng lệnh được lưu trong các biến đặc biệt. Ví dụ, đoạn script dưới đây sẽ gán giá trị của đối số thứ nhất cho biến name:

name=$1
 
echo $name

Chạy script trên với 1 đối số:

 ./bash.sh insomnia
insomnia

Một cách tương tự, đối số thứ 2 sẽ được lưu ở trong biến $2.

Info

Một số biến khác:

  • $#: số lượng đối số
  • $0: tên file của script
  • $@: tất cả các đối số ở dạng chuỗi phân cách với nhau bằng khoảng trắng

Chúng ta cũng có thể dùng lệnh read để đọc giá trị của biến từ bàn phím:

echo Enter your name
 
read name
 
echo "Your name is $name"

Khi chạy script thì nó sẽ đợi chúng ta nhập giá trị vào:

 ./bash.sh
Enter your name
insomnia
Your name is insomnia

Arrays

Mảng có cú pháp như sau:

transport=('car' 'train' 'bike' 'bus')

Truy xuất từng phần tử thông qua toán tử [] cùng index:

echo ${transport[1]}

Lưu ý là ta dùng toán tử ${} để truy xuất phần tử của mảng thay vì dùng $.

Nếu dùng $ thì sẽ mang ý nghĩa là lấy giá trị của mảng và giá trị của nó sẽ luôn là phần tử đầu tiên. Lý do là vì bản chất của mảng là con trỏ trỏ đến phần tử đầu tiên.

Ví dụ, xét đoạn script sau:

transport=('car' 'train' 'bike' 'bus')
 
echo $transport[2]

Kết quả khi thực thi:

 ./bash.sh
car[2]

Chúng ta có thể truy xuất tất cả các phần tử của mảng như sau:

echo ${transport[@]}

Với @ có nghĩa là tất cả các đối số.

Nếu muốn xóa một phần tử khỏi mảng thì ta dùng lệnh unset:

unset transport[1]

Khi dùng lệnh echo với phần tử đã bị xóa thì sẽ không có output.

Gán giá trị cho phần tử vừa bị xóa:

transport[1]='trainride'

Conditionals

Cú pháp của câu lệnh điều kiện:

if [ something comparison something ]
 
then
	something
else
	something different
fi

Ví dụ:

count=10
 
if [ $count -eq 10 ]
 
then 
	echo "true"
else
	echo "false"
fi

Kết quả khi thực thi sẽ là true.

Một số toán tử khác:

OperatorDescription
-eqKiểm tra xem giá trị của hai toán hạng có bằng nhau hay không; nếu đúng, điều kiện trở thành đúng.
-neKiểm tra xem giá trị của hai toán hạng có bằng nhau hay không; nếu giá trị không bằng nhau, điều kiện trở thành đúng.
-gtKiểm tra xem giá trị của toán tử trái lớn hơn giá trị của toán tử phải; nếu đúng, điều kiện trở thành đúng.
-ltKiểm tra xem giá trị của toán tử trái nhỏ hơn giá trị của toán tử phải; nếu đúng, điều kiện trở thành đúng.
-geKiểm tra xem giá trị của toán tử trái lớn hơn hoặc bằng giá trị của toán tử phải; nếu đúng, điều kiện trở thành đúng.

Đoạn script bên dưới sẽ kiểm tra sự tồn tại và quyền ghi của file. Nếu thỏa cả hai điều kiện thì sẽ ghi vào file chuỗi “hello”. Nếu nó không tồn tại thì sẽ tạo mới file rồi ghi chuỗi “hello”:

 
filename=$1
 
if [ -e "$filename" ] && [ -w "$filename" ]
then
	echo "hello" > $filename
else
	touch $filename
	echo "hello" > $filename
fi

Giải thích các option:

  • -e: kiểm tra sự tồn tại của file
  • -w: có quyền ghi vào file

Một số option khác:

  • -r: có quyền đọc
  • -x: có quyền thực thi
  • -d: kiểm tra xem có phải là thư mục

Kết quả thực thi:

 ./bash.sh hello
 
 l
total 16K
drwxr-xr-x  2 aleister aleister 4.0K Mar 29 22:53 .
drwxr-xr-x 11 aleister aleister 4.0K Mar 29 21:46 ..
-rwxr-xr-x  1 aleister aleister  152 Mar 29 22:53 bash.sh
-rw-r--r--  1 aleister aleister    6 Mar 29 22:53 hello
 
 cat hello
hello
list
from outgoing([[TryHackMe - Bash Scripting]])
sort file.ctime asc

Resources