NỘI DUNG
Tiếp theo nội dung Bash Script – La liếm với bộ 3 Variable, Argument & User Input, như đã hứa hẹn, kỳ này tôi sẽ chiến với Conditional statements (tôi tạm dịch là mệnh đề điều kiện). Ngoài ra, một đối tượng khác có liên quan là Boolean Logical Operations (tạm dịch là các phép toán luận lý logic) cũng sẽ được đề cập.
Nội dung kỳ này hướng đến nhóm đối tượng gần như chưa từng đụng tới programming (lập trình). Nếu đã biết sơ bộ về programming với các ngôn ngữ khác (ví dụ Python), bạn có thể lướt nhanh qua các phần cơ bản và tập trung vào các điểm khác biệt (về Syntax – cú pháp và cách xử lý) đặc trưng của Bash script.
Lưu ý: Nếu chưa xem phần trước thì bạn chịu khó de lại để tìm hiểu các nội dung quan trọng sau (kỳ trước tôi nhai đi nhai lại đám này nhiều quá nên giờ ngán lắm rồi):
- #!/bin/bash;
- read command;
- Tạo Bash script với text editor;
- Cấp quyền thực thi cho file với chmod;
- Chạy file Bash script.
#1 Dàn cảnh với Conditional statements trong Bash script
#1.1 Conditional statements – basic syntax
Conditional statements như bạn có thể đoán, là nhằm hỗ trợ việc lập kịch bản để thực hiện các hành động khác nhau tùy theo điều kiện thực tế. Và cũng như phần lớn các ngôn ngữ lập trình khác, dạng phổ biến nhất với Bash script cũng là đám if/elif/else.
Không nói dông dài nữa, tôi múc ngay cái ví dụ cho dễ hình dung với file test_if.sh có nội dung như sau:
#!/bin/bash
read -p "What is your math grade: " grade
if [ $grade -lt 5 ]
then
echo "You died!"
fi
Kết quả chạy thử như sau:
Để dễ hình dung, bạn có thể phân tích dựa trên cú pháp đơn giản của thằng if như sau:
if [ <conditions> ]
then
<actions>
fi
Như vậy, với ví dụ test_if.sh:
- <conditions> sẽ tương ứng với “$grade -lt 5”;
- < actions> sẽ tương ứng “echo “You died!””;
Dịch ra “tiếng người” phần xử lý của ví dụ nói trên: “Nếu điều kiện Grade (điểm) thấp hơn 5 là đúng, hiển thị dòng chữ ‘You died!’¸còn không đúng thì thôi”
Lưu ý:
- Đừng quên space (khoảng trắng) trước và sau cái <conditions>;
- Bỏ cái ngoặc vuông “[ ]” script chạy cũng được nhưng nhìn chung bạn nên tập thói quen đặt <conditions> bên trong cho gọn đẹp và dễ mần việc về sau;
- Nhớ ở đây có cái fi ở cuối cùng.
#1.2 Conditional statements – Operator
Trong ví dụ trên còn một thằng tôi chưa đề cập đó là -lt nằm trong <conditions>. lt (viết tắt của “less than”) là một trong các operator (tạm dịch là toán tử) phổ biến thường thấy trong các <conditions>. Ngoài thằng này, bạn còn có thể gặp đám sau:
Operator | Mô tả |
-n STRING | STRING (chuỗi ký tự) có độ dài lớn hơn không |
-z STRING | STRING (chuỗi ký tự) có độ dài lớn bằng không |
STRING1 != STRING2 | STRING1 không bằng STRING2 |
STRING1 = STRING2 | STRING1 bằng STRING2 |
INTEGER1 -eq INTEGER2 | INTEGER1 bằng INTEGER2 |
INTEGER1 -ne INTEGER2 | INTEGER1 không bằng INTEGER2 |
INTEGER1 -gt INTEGER2 | INTEGER1 lớn hơn INTEGER2 |
INTEGER1 -lt INTEGER2 | INTEGER1 nhỏ hơn INTEGER2 |
INTEGER1 -ge INTEGER2 | INTEGER1 lớn hơn hoặc bằng INTEGER 2 |
INTEGER1 -le INTEGER2 | INTEGER1 nhỏ hơn hoặc bằng INTEGER 2 |
-e FILE | FILE tồn tại |
-r FILE | FILE tồn tại và có read permission (quyền đọc) |
-s FILE | FILE tồn tại và không rỗng |
-w FILE | FILE tồn tại và có write permission (quyền ghi) |
-x FILE | FILE tồn tại và có execute permission (quyền thực thi) |
Lưu ý: Danh sách trên chỉ là mang tính chất giới thiệu, tùy nhu cầu thực tế mà bạn search thêm để biết cách xử lý. Ví dụ như muốn biết chi tiết hơn về việc kiểm tra file/directory có tồn tại thì bạn có thể đọc thằng này How to Check if a File or Directory Exists in Bash | Linuxize.
#1.3 Conditional statements – đẻ nhánh với Elif và Else
Với cái if syntax nói ở Mục 1.1, bạn chỉ có khả năng xử lý một tình huống khi <conditions> có kết quả là True. Nếu muốn xử lý tình huống nó ra kết quả False, bạn sẽ cần dùng đến nhánh Else theo cú pháp sau:
if [ <conditions> ]
then
<actions>
else
<other actions>
fi
Tôi thử với file test_if_again.sh với nội dung như sau:
#!/bin/bash
read -p "What is your math grade: " grade
if [ $grade -lt 5 ]
then
echo "You died!"
else
echo "Congrats!"
fi
Kết quả chạy thử như sau:
Như vậy với test_if_again.sh, phần actions bên trong else sẽ được thực thi nếu <conditions> có kết quả là False (nghĩa là grade lớn hơn hoặc bằng 5).
Vậy nếu bạn thích rối rắm hơn và đẻ ra thêm tình huống xử lý khi “grade đúng bằng 5” thì sao? Lúc này, bạn có thể dùng thêm elif như syntax sau.
if [ <conditions> ]
then
<actions>
efif [ <other conditions> ]
then
<other actions>
else
<other actions>
fi
Lưu ý: elif có syntax tương tự như nhánh if, bạn nhớ phần space (khoảng trắng) trước và sau cái <conditions> và then đi kèm.
Tôi tiếp tục demo với ví dụ test_if_again_x2.sh có nội dung như sau:
#!/bin/bash
read -p "What is your math grade: " grade
if [ $grade -lt 5 ]
then
echo "You died!"
elif [ $grade -eq 5 ]
then
echo "So close!"
else
echo "Congrats!"
fi
Kết quả chạy thử như sau:
Đến đây coi như bạn đã nắm được “linh hồn” của đám Conditional statements. Nhưng nếu như thế vẫn chưa đáp ứng được dã tâm của bạn thì sao? Rất may mắn, bạn còn có Boolean Logical Operations hỗ trợ để kết hợp với Conditional statements phục vụ các ngữ cảnh phức tạp hơn.
#2 Phức tạp hóa vấn đề với Boolean Logical Operations trong Bash script
#2.1 Xử lý command lists với Boolean Logical Operations
Boolean Logical Operations nói chung và 2 thằng phổ biến nhất là AND (&&) và OR (||) có khá nhiều đất diễn với Bash script. Bên cạnh việc hỗ trợ kết hợp với Conditional statements nói trên bạn còn có thể sử dụng đám này với command lists (chuỗi các command có thể kết nối với nhau).
Nếu bạn còn nhớ (quên cũng không sao, vì tôi sắp nhắc lại đây), command lists đơn giản gồm 2 command ls và grep với piping (|) như sau:
ls -la /usr/bin | grep zip
Lưu ý: Thằng piping tôi có bàn kỹ ở nội dung Giải ngố Kali Linux – Phần 5: Nâng cấp kỹ năng tìm kiếm trên Linux với grep command
Như bạn thấy output của thằng ls sẽ được hốt và dẫn sang grep (nhờ piping) để xác định cái nào trong đám output có dính líu đến zip.
Với Boolean Logical Operations, nguyên tắc xử lý cũng kiểu tương tự như vậy (nhưng có chọn lọc hơn). Tôi ví dụ minh họa ngay cho dễ hình dung như sau:
test_user=testkali
grep $test_user /etc/passwd && echo "$test_user found!"
Lưu ý:
- Việc gán giá trị và tham chiếu đến Variable (test_user trong ví dụ trên) tôi đã giới thiệu kỹ trong nội dung Bash Script – La liếm với bộ 3 Variable, Argument & User Input. Nếu chưa rõ thì bạn chịu khó quay lại đó xem;
- Nếu bạn không biết USER và HOSTNAME tương ứng trên máy bạn là gì thì có thể nhìn vô chỗ đám chữ màu đỏ trên termial để đọc thông tin theo cú pháp USER@HOSTNAME (của tôi là testkali@kali) hoặc có thể kiểm tra lại kiểu như sau.
Dễ thấy (thú thật, lần đầu gặp thứ này tôi thấy khó thí mịa chứ dễ dàng gì), command lists sử dụng grep để thực hiện tìm kiếm username “testkali” có hiện diện trong file /etc/passwd hay không. Nếu kết quả của command grep trả về là True (tức là có tồn tại username “testkali” trong file /etc/passwd), command echo phía sau AND (&&) sẽ được thực thi (còn không có thì terminal sẽ đáp lại bằng thái độ im lặng đáng sợ).
Nếu không thích thái độ lạnh nhạt đó, bạn có thể cập nhật lại command lists như sau.
test_user=testkali
grep $test_user /etc/passwd && echo "$test_user found!" || echo "$test_user not found!"
Cũng lại dễ thấy, nếu kết quả của command grep trả về là False (ứng với tình huống không tồn tại username “testkali_fake” trong file /etc/passwd), command echo phía sau OR (||) sẽ được thực thi để báo cho bạn biết tình hình dò tìm username.
#2.2 Giao lưu phối hợp Conditional statements với Boolean Logical Operations
Quay trở lại câu chuyện với Conditional statements, tôi sẽ phức tạp hóa thêm vấn đề bằng cách kết hợp với Boolean Logical Operations như file test_if_again_x3.sh có nội dung sau:
#/bin/bash
if [ $USER == 'testkali' ] && [ $HOSTNAME == 'kali' ]
then
echo "Yes, username is $USER AND hostname is $HOSTNAME!"
else
echo "Who am I?"
fi
Kết quả chạy thử:
Với ví dụ trên, chỉ khi cả $USER VÀ $HOSTNAME khớp với điều kiện kiểm tra, Conditional statements lúc này trả về giá trị True, bạn mới thấy dòng thông báo hiển thị $USER và $HOSTNAME.
Tôi thử đổi Conditional statements liên quan đến $USER với giá trị trị vớ vẩn (testkali_fake) thì lúc này giá trị trả về sẽ là False nên bạn sẽ đọc được dòng echo của nhánh else bên dưới.
Kết quả chạy lại:
Nếu muốn chơi nhẹ nhàng tình cảm hơn, bạn có thể đổi điều kiện kiểm tra sang OR (||) thay vì AND (&&) như file test_if_again_x4.sh sau:
#/bin/bash
if [ $USER == 'testkali' ] || [ $HOSTNAME == 'not kali' ]
then
echo "Yes, username is $USER OR hostname is $HOSTNAME!"
else
echo "Seriously, you don’t even know your name?"
fi
Kết quả chạy thử:
Lúc này, chỉ cần ăn hên dò trúng một trong 2 điều kiện $USER HOẶC $HOSTNAME là Conditional statements trả về giá trị True để bạn tha hồ tung tóe.