Sau khi các bạn đã đọc bài viết 04_Linux_Introduction, chúng ta sẽ đọc về bài bash-shell trong linux. Đây là 1 script quan trọng để người dùng có thể tương tác được với OS. Và cũng từ script Shell này ta có thể viết các tool để phục vụ cho các công việc trong linux như Flash SD card, tạo các test case ...
Nội dung của bài viết gồm có những phần sau nhé 📢📢📢:
Bash là gì?
- Bash là viết tắt của Born Again Shell.
- Bash là một shell được viết miễn phí để thay thế cho Bourne Shell chuẩn (/bin/sh) ban đầu được Steve Bourne viết cho các hệ thống UNIX.
- Nó có tất cả các tính năng của Bourne Shell ban đầu, cùng với các bổ sung giúp dễ dàng lập trình và sử dụng từ dòng lệnh hơn.
- Vì là Phần mềm Miễn phí, nó đã được sử dụng làm shell mặc định trên hầu hết các hệ thống Linux.
- Shell Bush là shell được sử dụng phổ biến nhất và do tính đa dạng của các hệ thống Linux.
- Bằng cách viết kịch bản cho chương trình hay nhất, bạn có thể khá tự tin rằng kịch bản của mình sẽ hiệu quả khi bạn chuyển nó sang các máy khác, điều này có thể giúp bạn tiết kiệm rất nhiều công việc.
How is bash different from DOS cmd
- Phân biệt chữ hoa chữ thường: bash phân biệt chữ hoa chữ thường, nhưng DOS thì không.
- "/" so với "": Trong DOS, dấu gạch chéo xuôi "/" là dấu phân cách tham số lệnh, trong khi dấu gạch chéo ngược "" là dấu phân cách thư mục. Trong Linux/UNIX, dấu "/" là dấu phân cách thư mục, và dấu "" là ký tự thoát.
Shell là gì?
- Shell là một chương trình cung cấp giao diện giao tiếp giữa người dùng và hệ điều hành (OS). Hệ điều hành khởi động một shell cho mỗi người dùng khi người dùng đăng nhập hoặc mở một cửa sổ terminal hoặc console.
- Viết kịch bản cho phép tự động hóa.
Kịch bản
- Một kịch bản gồm 3 phần: Mở đầu, phần giữa và phần cuối
- Dòng đầu cho biết Shell sử dụng trình thông dịch nào để đọc
- Phải có 1 dòng cách ra giữa dòng đầu và code
- Ghi Exit 0 là thành công, còn từ 1-255 là không thành công
- Chmod + x name_file: Cấp quyền thực thi
Comment
- Có 2 kiểu là comment 1 dòng và comment nhiều dòng
Quyền file
- Linux quản lý tất cả mọi thứ như 1 file. Các loại file trong linux:
Chữ R: là Regular file, là các file thông thường như text file, executable file
Chữ D: là Directories file, file chứa danh sách các file khác.
Chữ C: là Character Device file, file đại diện cho các thiết bị không có địa chỉ vùng nhớ.
Chữ B: là Block Device file, file đại diện cho các thiết bị có địa chỉ vùng nhớ
Chữ L: là Link files, file đại diện cho một file khác
Chữ S: là Socket file, file đại diện cho 1 socket
Chữ P: là Pipe file, file đại diện cho 1 pipe
Dấu " - ": là file thông thường- Để hiển thị thông tin file ta gõ : ls -l
- Khi này, số hardlink sẽ là có bao nhiêu file cùng trỏ tới 1 phân vùng nhớ thì đó là số hardlink của file.
Thay đổi quyền file
- Để thay đổi quyền của file ta dùng câu lệnh chmod. Có thể vào LINK NÀY để xem quyền trực quan hơn
chmod 744 Name_file
chmod o+r test.txt: thêm quyền read.
chmod u-r test.txt: bỏ quyền read.Path environment
- PATH là một biến môi trường trong Linux, cho shell biết thư mục nào cần tìm kiếm các tệp thực thi để đáp ứng các lệnh do người dùng đưa ra.
- Thường được định nghĩa trong /etc/bash.bashrc và ~/.bashrc
PATH=/usr/bin:/bin:/usr/local/bin
Phân cách bằng ký tự ":"
Hệ thống sẽ tìm kiếm lệnh từ trái sang phải
Có thể lấy PATH hiện tại bằng lệnh "echo $PATH"-
Bình thường ta muốn chạy file gì đó thì phải cd tới folder chứa file đó để chạy, vậy bây giờ ta muốn chạy file đó ở bất kì chỗ nào không cần đường dẫn tuyệt đối hoặc tương đối trỏ tới file thì ta phải làm như thế nào?
-
Đầu tiên ta sẽ gõ: echo "$PATH" để xem trong PATH đang có những đường dẫn nào
- Khi này, để thêm 1 đường dẫn vào 1 PATH ta sẽ có 2 cách như dưới
- Thêm tạm thời:
- Khi tắt máy bật lại thì sẽ mất
- Cách thêm: export PATH=$PATH:/home/hulatho/bash_shell
- Khi này ta gõ echo "$PATH" ta sẽ thấy đường dẫn trên đã được thêm vào cuối của biến PATH
- Thêm tạm thời:
- Thêm trọn đời:
vim ~/.profile
Thêm export PATH=$PATH:/home/hulatho/bash_shell vào file
source ~/.profile để lưu nội dung lại- Như ta biết, khi chạy 1 file, nó sẽ tìm đường dẫn trong biến PATH này, tìm từ trên xuống dưới nếu có thì file đó được chạy luôn. Như vậy ta sẽ cần có thêm sự ưu tiên, nghĩa là sẽ tìm PATH của ta trước. Để có sự ưu tiên trước thì ta sẽ thêm đường dẫn trước $PATH, còn không cần ưu tiên thì thêm đường dẫn vào sau $PATH
❌ export PATH=$PATH:/home/hulatho/bash_shell
export PATH=your_directory:$PATH
✔️ export PATH=/home/hulatho/bash_shell:$PATHVariable
- Có 2 loại biến là biến có sẵn và biến ta tự tạo
- Các biến có sẵn như: PATH, HOME, HOSTNAME, PS1
- PS1: là cái nhắc lệnh cho ta
- Ta có thể sửa đổi bằng cách PS1="Ghi vào đây"
- https://ezprompt.net/ lên trang này để lấy cái "Ghi vào đây"
- Quay trở về ban đầu thì: source ~/.bashrc
- PS1: là cái nhắc lệnh cho ta
- Các biến ta tự tạo sẽ như ảnh bên dưới
- Các biến có sẵn như: PATH, HOME, HOSTNAME, PS1
- Chuyển chữ hoa thành chữ thường
- Chuyển chữ thường thành chữ hoa
- Đếm kí tự và cắt chuỗi
- Lấy đầu ra của 1 lệnh và gán
- Tính toán
- ${parameter}
- $(command)
- $((expression))
- bc để ra số thập phân, scale=2, lấy 2 chữ số thập phân
- Các kí tự đặc biệt
- ~- : Thay đổi về thư mục trước đó
- ~ : Đưa ra đường dẫn đầy đủ tưới user
- ~+ : lấy ra đường dẫn PWD hiện tại
- : Ký tự thoát. Nếu bạn muốn tham chiếu đến một ký tự đặc biệt, trước tiên bạn phải "thoát" nó bằng dấu gạch chéo ngược. Ví dụ: touch /tmp/filename*
- /: Dấu phân cách thư mục, dùng để phân tách một chuỗi tên thư mục. Ví dụ: /usr/src/linux
?: Represents a single character in a filename.
Ex: hello?.txt can represent hello1.txt, helloz.txt, but not hello22.txt
[ ]: Can be used to represent a range of values, e.g. [0-9], [A-Z], etc.
Ex: hello[0-2].txt represents the names hello0.txt, hello1.txt, and hello2.txt
|: "Pipe". Redirect the output of one command into another command.
Ex: ls | less
>: Redirect output of a command into a new file. If the file already exists,
over-write it.
Ex: ls > myfiles.txt
>>: Redirect the output of a command onto the end of an existing file.
Ex: echo "Mary 555-1234" >> phonenumbers.txt
<: Redirect a file as input to a program.
Ex: more < phonenumbers.txt
;: Command separator. Allows you to execute multiple commands on a single line.
Ex: cd /var/log ; less messages
&&: Command separator as above, but only runs the second command if the first one finished without errors.
Ex: cd /var/logs && less messages
&: Execute a command in the background, and immediately get your shell back. Same as non-blocking call model.
Ex: find / -name core > /tmp/corefiles.txt &- Tạo ra nhiều như hàm Range
- Tạo ra 12 tháng, mỗi tháng có 31 ngày là file
Khi chạy 1 commad line có 5 bước:
+ Tokenisation
+ Command identification
+ Shell expansions
+ Quote removal
+ RedirectionsBước 1: Tokenisation
- Đi tìm kiếm nơi code command bắt đầu và kết thúc bằng các kí tự đặc biệt bên dưới và được sử dụng để chia nhỏ dòng lệnh ra
|
&
;
()
<>
Space, tab, newline- Ví dụ:
Ví dụ: echo $name > tho.txt
+ Thằng này ban đầu nó chỉ là 1 string thôi
+ Sau đó shell bắt đầu xác định các kí tự đặc biệt trong đây
+ Sau đó nó tìm xem có 1 kí tự nào không, để biết có toán tử nào trong đây không, còn lại sẽ là 1 từ (như vậy sẽ có 1 toán tử chuyển hướng và 3 từ) Bước 2: Command identification - Nhận dạng lệnh
Shell chia các command thành các lệnh đơn giản hoặc lệnh ghép
- Lệnh đơn giản như echo chẳng hặn
- Tất cả các lệnh đơn giản đều được kết thúc bằng 1 toán tử điều khiển
Newline
|
||
&
&&
;
;;
;&
;;&
|&
(
)- Ví dụ sau đây là kết thúc bởi dấu ; và newline
- Lệnh phức tạp như If, for, while...
Bước 3: Shell expansions
- Thực hiện mở rộng câu lệnh
- Có bốn giai đoạn mở rộng Shell.
Stage 1: Brace expansion
Stage 2: include: Parameter, arithmetic, command substitution
Stage 3: Word splitting - Tách từ
Stage 4: Globbing- Word splitting
- Tách từ
- Các kí tự tách từ được lưu trong biến IFS
- Có thể thấy biến nay đang chứa 1 dấu cách, 1 dấu tab và xuống dòng
Bước 4: Quote removal - Loại bỏ kí tự đặc biệt
Mục đích của việc trích dẫn là loại bỏ ý nghĩa đặc biệt khỏi các ký tự đặc biệt.
\
``
""- Ví dụ
Name="Tho" out="out.txt”"
Echo $name > $out
Step 1: tìm Word và toán tử Echo $name > $out
Step 2: nhận dạng command Có 1 newline ở cuối dòng, nhưng bị ẩn
Step 3: Mở rộng Echo Tho > out.txt
Step 4: Remove Quote Không có
Step 5: Chuyển hướng Echo Tho --> stdout ---> Out.txtBước 5: Redirections
- Echo "hello thonv" > output.txt
- Toán tử chuyển hướng > sẽ ghi đè nội dung hiện tại của tệp
- Toán tử chuyển hướng >> chuyển hướng Standard Output của lệnh tới một tệp.
- Toán tử chuyển hướng &> chuyển hướng Standard Output và lỗi đến cùng một nơi.
Sau khi xong 5 bước này thì bash sẽ thực hiện execute command line
Positional Input
Special param
- $@ : lấy tất cả các tham số truyền vào, khi ở giữa là dấu cách
- $* : Khi IFS là gì, thì param lấy vào sẽ có dấu đó ở giữa
Read comamnd
Ứng dụng
Điều kiện biến
string1 = string2 : true nếu 2 chuỗi bằng nhau
string1 != string2 : true nếu 2 chuỗi không bằng nhau
-n string1 : true nếu tring1 không rỗng
-z string1 : true nếu tring1 rỗng
expression1 -eq expression2 : true nếu 2 biểu thức bằng nhau
expression1 -ne expression2 : true nếu 2 biểu thức không bằng nhau
expression1 -gt expression2 : true nếu biểu thức expression1 lớn hơn expression2
expression1 -ge expression2 : true nếu biểu thức expression1 lớn hơn hoặc bằng expression2
expression1 -lt expression2 : true nếu biểu thức expression1 nhỏ hơn expression2
expression1 -le expression2 : true nếu biểu thức expression1 nhỏ hơn hoặc bằng expression2
!expression : true nếu biểu thức expression là false (toán tử not)Điều kiện Fille
-d file : true nếu file là thư mục
-e file : true nếu file tồn tại trên đĩa
-f file : true nếu file là tập tin thông thường
-g file : true nếu set-group-id được thiết lập trên file
-r file : true nếu file cho phép được
-s file : true nếu file có kích thước khác 0
-u file : true nếu set-ser-id được áp đặt trên file
-w file : true nếu file cho phép ghi
-x file : true nếu file được phép thực thiIf else
Select và Case
Lấy option từ bàn phím
While
Array
For array
Tạo Array từ 1 fille
Debug
- Lên trang https://www.shellcheck.net/ để check xem file lỗi chỗ nào
- Gõ man name_lenh để xem trợ giúp
- Gõ help name_lenh
Function
Số Nguyên tố
Tạo Folder
Tổng Hợp lại
Does not have type definition
Declare by: <var_name>=[value] (no spaces at =)
Used by: $var_name, ${var_name}
Delete by: unset <var_name>
Print to console by: printf, echo
Read from console by: read
Numeric variable: var_num=1
String variable: var_str=“This is string”
Math expression: var_num=`expr $var_num + 1`
$0: contains command that you used to run the script
$1->: the argument number 1->
$#: number of positional argument
$@: array of positional arguments
$$: PID of current process
$?: exit code of last command (returned by exit command)
test là một lệnh tích hợp sẵn của BASH, nó đánh giá nhiều loại
biểu thức, từ thuộc tính tệp đến số nguyên và chuỗi.
Phiên bản thay thế của test là [ … ] (khoảng trắng sau [ và trước ])
File test:
[ -f ~/test ] # True if ~/test is a regular file
[ -e /etc/fstab ] # True if file /etc/fstab exists
Integer test:
[ x -eq 1 ] # True if x == 1
[ x -ne 1 ] # True if x != 1
[ x -gt 1 ] # True if x > 1
String test:
[ x = “a” ] # True if x content is equal to “a”
[ x != “a” ] # True if x content is not “a”
BASH evaluate expression [[ ]]
[[ ]] is BASH shell grammar, not command
Supports same operator as test
More than test, it can evaluate regular expression string=“whatever”
[[ $string =~ h[aeiou] ]] # True
[[ $string =~ h[sdfghijk] ]] # False
BASH conditional operators
<command 1> && <command 2>: do <command 2> after and if <command 1> return True
<command 1> || <command 2>: do <command 2> after and if <command 1> return False
[ -f /etc/fstab ] && cat /etc/fstab || echo “not exists”
[ -f /etc/fstaba ] && cat /etc/fstab || echo “not exists”
BASH branch with if
if <condition list>
then
<commands>
fi
if <condition list>; then <commands>; fi
BASH branch with case
case WORD in
PATTERN) COMMANDS ;;
PATTERN) COMMANDS ;; ## optional
esac
BASH loop
While loop
while <list>
do
<list>
done
Until loop
until <list>; do <list>; done
For loop
for (( n=1; n<=10; ++n )); do echo "$n"; done
for var in Canada USA Mexico; do printf "%s\n" "$var"; done
BASH function
<function_name>()
{
<commands>;
}Ở bài viết này hi vọng các bạn đã có hiểu biết sơ lược về Bash-Shell và có thể sử dụng 1 cách cơ bản để phục vụ cho công việc của chúng ta. Trên mạng có rất nhiều tài liệu tham khảo cũng như sách vở. Dưới đây mình sẽ share vài file pdf cũng như link về bash-shell.
- Advanced Bash-Scripting Guide.pdf
- Bash Guide for Beginners.pdf
- Bash.Quick.Reference.2006.pdf
- cheatsheet
- Ex1: Viết script tìm số lớn nhất trong 3 số được nhập từ dòng lệnh
- Ex2: Viết script tính tổng các ký số của một số được nhập vào vd: tinh 1234 -> 10
- Ex3: Tạo menu tương tác với người dùng:
---------------------------------------Main Menu---------------------------------------
[1] Show today date/time
[2] Show all files in current directory
[3] Show users
[4] Show calendar
[5] Exit/Stop- Ex4: In ra các phần tử chẵn lẻ,Tính tổng các phần tử trong mảng (dùng hàm tổng 2 số)
- Ex5: Viết script để xác định đường dẫn một file và kiểm tra xem file đó có tồn tại hay không
- Ex6: Chương trình đếm số dòng/từ của một file
- Ex7: Phân tích 5 bước của 2 câu lệnh bên dưới
Echo "$name" > "$out"
Echo "$(ls *.txt)"[2] Advanced Bash-Scripting Guide.pdf
[3] Bash Guide for Beginners.pdf
[4] Bash.Quick.Reference.2006.pdf






















































