Làm quen với Shell Script
Bài đăng này đã không được cập nhật trong 8 năm
Shell?
Shell là một chương trình thông dịch lệnh của một hệ điều hành, cung cấp cho người dùng khả năng tương tác với hệ điều hành bằng cách gõ từng lệnh ở chế độ dòng lệnh, đồng thời trả lại kết quả thực hiện lệnh lại cho người sử dụng. Shell cung cấp tập hợp các lệnh đặc biệt mà từ đó có thể tạo nên chương trình, khi đó được gọi là shell script.
Ngoài các lệnh đơn giản của hệ thống Unix shell còn bổ sung thêm các cấu trúc phức tạp như điều khiển rẽ nhánh,vòng lặp. Trong MS-DOS thì shell chính là Command, trong Linux thì có nhiều loại shell khác nhau như sh, zsh, bash, csh... trong đó phổ biến nhất vẫn là bash shell (shell mặc định cho rất nhiều distro khác nhau).
Shell Prompt
Nếu bạn là người sử dụng terminal hàng ngày thì cái bạn phải nhìn thấy nhiều nhất chính là cái gọi là “Command prompt”, nó chính là cái này:
Phía sau $
chúng ta có thể bắt đầu gõ lệnh
thao@bla-bla ~ $ date
Thứ năm, 26 Tháng mười một năm 2015 17:50:04 ICT
Chúng ta có thể làm đuợc nhiều thứ vui vẻ với prompt này bằng cách thay biến PS1, tham khảo thêm ở đây: Bash Shell PS1: 10 Examples to Make Your Linux Prompt like Angelina Jolie
Shell types
Có 2 loại shell chính:
- Bourne shell (mặc định có dấu nhắc lệnh là $ như ở trên)
- C shell (dấu nhắc lệnh là %)
Trong Bourne shell còn có các loại khác nhau như:
- Bourne shell (sh)
- Korn shell (ksh)
- Bourne Again shell (bash)
- POSIX shell (sh)
C shell thì có:
- C shell (csh)
- TENEX/TOPS C shell (tcsh)
Shell Script
Về cơ bản shell script là 1 tập hợp các lệnh được thực thi nối tiếp nhau, bắt đầu 1 shell script thường có ghi chú comment mở đầu bằng #
như này:
#!/bin/bash
# Author : Không AI
# Copyright (c) Viblo.asia
# Script chạy linh tinh lắm
HELLO="Xin chào, "
HELLO=$(printf "%s %s" "$HELLO" "$(whoami)" "!")
DAY="Hôm nay là ngày "
DAY=$(printf "%s %s" "$DAY" "$(date)")
echo $HELLO
echo $DAY
- trước khi làm bất cứ điều gì với script, cần thông báo với system rằng chuẩn bị có shell chạy bằng dòng lệnh
#!/bin/bash
- để soạn thảo shell script thì có thể gõ ngay trên terminal hoặc dùng các trình soạn thảo nào mà bạn thích, vim, gedit, kate,... sau đó lưu lại file
*.sh
, ví dụtest.sh
- sau đó thiết lập quyền thực thi cho shell
$chmod +x test.sh
- rồi chạy script bằng 1 trong 3 cách:
bash test.sh
,sh test.sh
,./test.sh
kết quả:
thao@bla-bla ~ $ bash test.sh
Xin chào, thao!
Hôm nay là ngày Thứ năm, 26 Tháng mười một năm 2015 18:19:25 ICT
Biến trong shell
Đặt tên
Như mọi ngôn ngữ khác, tên biến chỉ bao gồm các chữ cái a
đến z
, từ A
đến Z
, chữ số từ 0
tới 9
và dấu _
, tên biến không được bắt đầu bằng chữ số.
Khai báo
variable_name=variable_value
Ví dụ:
THAO="Nguyễn Thế Thạo"
Sử dụng
THAO="Nguyễn Thế Thạo"
echo $THAO
Biến Read-only
Sau khi khai báo biến này, thì giá trị của biến không thể bị thay đổi.
thao@bla-bla ~ $ THAO="Nguyễn Thế Thạo"
thao@bla-bla ~ $ readonly THAO
thao@bla-bla ~ $ THAO="Muốn Thay Tên Khác"
bash: THAO: readonly variable
Xóa giá trị của biến
thao@bla-bla ~ $ a="value"
thao@bla-bla ~ $ echo $a
value
thao@bla-bla ~ $ unset a
thao@bla-bla ~ $ echo $a
thao@bla-bla ~ $
Các loại biến
- Biến hệ thống: tạo ra và quản lý bởi system, tên là chữ hoa, ví dụ
thao@bla-bla ~ $ echo $SHELL
/bin/bash
thao@bla-bla ~ $ echo $TERM
xterm
- Biến do người dùng định nghĩa: tạo ra và quản lý bởi người dùng, tên lung tung, thỏa mãn yêu cầu đặt tên của shell.
Mảng
NAME[0]="Zara"
NAME[1]="Qadir"
NAME[2]="Mahnaz"
NAME[3]="Ayan"
NAME[4]="Daisy"
Nếu dùng ksh shell thì có thể khai báo:
set -A array_name value1 value2 ... valuen
Nếu dùng bash shell thì khai báo thế này:
array_name=(value1 ... valuen)
Để sử dụng 1 giá trị trong mảng:
${array_name[index]}
hoặc tất cả giá trị trong mảng:
${array_name[*]}
${array_name[@]}
Ví dụ:
#!/bin/sh
NAME[0]="Zara"
NAME[1]="Qadir"
NAME[2]="Mahnaz"
NAME[3]="Ayan"
NAME[4]="Daisy"
echo "First Index: ${NAME[0]}"
echo "Second Index: ${NAME[1]}"
echo "First Method: ${NAME[*]}"
echo "Second Method: ${NAME[@]}"
Kết quả:
$./test.sh
First Index: Zara
Second Index: Qadir
First Method: Zara Qadir Mahnaz Ayan Daisy
Second Method: Zara Qadir Mahnaz Ayan Daisy
Các phép toán số học
Để thực hiện các phép toán số học, cần dùng expr
để thực hiện:
#!/bin/sh
val=`expr 2 + 2`
echo "Total value : $val"
Kết quả:
Total value : 4
Với $a
có giá trị 10 và $b
có giá trị 20, ta có bảng sau:
Phép tính | Ý nghĩa | Ví dụ |
---|---|---|
+ | Phép cộng | expr $a + $b trả kết quả 30 |
- | Phép trừ | expr $a - $b trả kết quả -10 |
* | Phép nhân | expr $a \* $b trả kết quả 200 |
/ | Phép chia | expr $b / $a trả kết quả 2 |
% | Phép chia lấy dư | expr $b % $a trả kết quả 0 |
= | Gán giá trị | a=$b giá trị của b sẽ gán cho $a , giờ $a có giá trị là 20 |
== | So sánh bằng, trả về true nếu 2 biến cùng giá trị | [ $a == $b ] trả về false |
!= | So sánh không bằng, trả về true nếu 2 biến khác giá trị | [ $a == $b ] trả về true |
Phép toán quan hệ
Vẫn với $a
có giá trị 10 và $b
có giá trị 20, ta có bảng sau:
Phép tính | Ý nghĩa | Ví dụ |
---|---|---|
-eq | Kiểm tra giá trị 2 toán tử có bằng nhau hay không, bằng thì trả về true | [ $a -eq $b ] trả kết quả không phải là true |
-ne | Kiểm tra giá trị 2 toán tử có bằng nhau hay không, không thì trả về true | [ $a -ne $b ] trả kết quả true |
-gt | Kiểm tra giá trị của toán tử bên trái có lớn hơn giá trị bên phải hay không, có trả về true | [ $a -gt $b ] trả kết quả không phải là true |
-lt | Kiểm tra giá trị của toán tử bên trái có nhỏ hơn giá trị bên phải hay không, có trả về true | [ $a -lt $b ] trả kết quả true |
-ge | Kiểm tra giá trị của toán tử bên trái có lớn hơn hoặc bằng giá trị bên phải hay không, có trả về true | [ $a -ge $b ] trả kết quả không phải là true |
-le | Kiểm tra giá trị của toán tử bên trái có nhỏ hơn hoặc bằng giá trị bên phải hay không, có trả về true | [ $a -le $b ] trả kết quả là true |
Cấu trúc rẽ nhánh
Ví dụ:
#!/bin/sh
a=10
b=20
if [ $a == $b ]
then
echo "a is equal to b"
fi
if [ $a == $b ]
then
echo "a is equal to b"
elif [ $a -gt $b ]
then
echo "a is greater than b"
elif [ $a -lt $b ]
then
echo "a is less than b"
else
echo "None of the condition met"
fi
Cấu trúc lặp
Vòng lặp while
#!/bin/sh
a=0
while [ $a -lt 10 ]
do
echo $a
a=`expr $a + 1`
done
Vòng lặp for
#!/bin/sh
for var in 0 1 2 3 4 5 6 7 8 9
do
echo $var
done
Vòng lặp until
#!/bin/sh
a=0
until [ ! $a -lt 10 ]
do
echo $a
a=`expr $a + 1`
done
Vòng lặp select
#!/bin/ksh
select DRINK in tea cofee water juice appe all none
do
case $DRINK in
tea|cofee|water|all)
echo "Go to canteen"
;;
juice|appe)
echo "Available at home"
;;
none)
break
;;
*) echo "ERROR: Invalid selection"
;;
esac
done
Kết quả của vòng select
$./test.sh
1) tea
2) cofee
3) water
4) juice
5) appe
6) all
7) none
#? juice
Available at home
#? none
Hàm
#!/bin/sh
# Define your function here
Hello () {
echo "Hello World"
}
# Invoke your function
Hello
Chạy script
$./test.sh
Hello World
Dùng hàm với parameters:
#!/bin/sh
# Define your function here
Hello () {
echo "Hello World $1 $2 $3"
}
# Invoke your function
Hello Nguyễn Thế Thạo
Kết quả:
$./test.sh
Hello World Nguyễn Thế Thạo
Lấy kết quả trả về từ hàm
#!/bin/sh
# Define your function here
Hello () {
echo "Hello World $1 $2 $3"
return 10
}
# Invoke your function
Hello Nguyễn Thế Thạo
# Capture value returnd by last command
ret=$?
echo "Return value is $ret"
Kết quả:
$./test.sh
Hello World Nguyễn Thế Thạo
Return value is 10
Một số ví dụ
Chạy thử một số script vô dụng này cho vui các bạn nhé (nhắc lại là vô dụng, chỉ để cho vui thôi nhé)
#!/bin/sh
for i in {1..9}; do for j in $(seq 1 $i); do echo -ne $i×$j=$((i*j))\\t;done; echo;done
#!/bin/bash
str=" 0 1 2 3 45 6 7 8 9 q w e r t y u o pa sd fgh jk lizxcvbnmQ WER TY U O P A S D FG HJ KLZX CV B NM"
color[0]='\E[30;40m'
color[1]='\E[31;40m'
color[2]='\E[34;40m'
color[3]='\E[37;40m'
clear
echo "hacking $1"
sleep 2
echo "Initializing"
sleep 2
echo "Server hacking module is loading"
sleep 2
echo "Server hacking module is ready"
sleep 2
echo "Hack module is starting in 5 seconds"
sleep 1
echo "4 seconds"
sleep 1
echo "3 seconds"
sleep 1
echo "2 seconds"
sleep 1
echo "1 seconds"
sleep 1
ping -c 3 $1
sleep 2
netstat
sleep 1
findsmb
sleep 1
for i in {1..10000}
do
number1=$RANDOM
let "number1 %= ${#str}"
number2=$RANDOM
let "number2 %=4"
echo -n -e "\033[1m${color[$number2]}${str:number1:1}\033[0m"
done
sleep 3
echo "$1 succesfully hacked!"
sleep 1
echo "PASSWORD ACCPTED: token is 453572345763425834756376534"
#!/bin/bash
#disables control c
trap '' 2
# disables control z
trap "" SIGTSTP
color='\E[30;40m'
clear
echo "Formating disk(s): " /dev/sd*
sleep 2
echo "Initializing..."
sleep 2
echo -ne "Are you sure you want to format these disks?(y/n): "
sleep 1
echo "Y"
sleep 1
echo "formating starts in 5 seconds"
sleep 1
echo "4 seconds"
sleep 1
echo "3 seconds"
sleep 1
echo "2 seconds"
sleep 1
echo "1 second"
sleep 1
for i in {1..50000}
do
echo -n -e "\033[1m${color}0\033[0m"
done
sleep 1
echo ""
echo /dev/sd* "are formatted."
sleep 1
echo "be sure to make sure you reboot to clear operating system from RAM"
Kết luận
Nguồn:
All rights reserved