Để đến với Control Structures thì chắc chúng ta cũng sẽ liên tưởng đến việc sẽ phải kiểm tra một cái gì đó, với những ngôn ngữ lập trình thông thường thì sẽ kiểu như a % 2 == 1
hay x > y
,v.v. Bashshell tất nhiên nó cũng có những điều kiện như vậy, tuy nhiên làm việc với BashShell chúng ta sẽ gặp những thứ này phổ biến hơn.
- | Details |
---|---|
File Operators | -------- |
-e "$file" | Trả về true nếu file đã tồn tại |
-d "$file" | Trả về true nếu file đã tồn tại và là một thư mục (lưu ý trong linux thư mục cũng là một file) |
-f "$file" | Trả về true nếu file đã tồn tại và là một regular file |
-h "$file" | Trả về true nếu file đã tồn tại và là một symbolic link |
String Comparators | -------- |
-z "$str" | True nếu độ dài của chuỗi là 0 |
-n "$str" | True nếu độ dài của chuỗi lớn hơn 0 |
"$str" = "$str2" | Đúng nếu chuỗi $ str bằng chuỗi $ str2. Không tốt cho so sánh số nguyên. Nó có thể hoạt động nhưng sẽ không nhất quán |
"$str" != "$str2" | True nếu hai tring khác nhau |
Integer Comparators | -------- |
$int1" -eq "$int2" | True nếu 2 số nguyên bằng nhau |
$int1" -ne "$int2" | True nếu 2 số nguyên không bằng nhau |
$int1" -gt "$int2" | True nếu số nguyên 1 lớn hơn số nguyên 2 |
$int1" -ge "$int2" | True nếu số nguyên 1 lớn hơn hoặc bằng số nguyên 2 |
$int1" -lt "$int2" | True nếu số nguyên 1 nhỏ hơn số nguyên 2 |
$int1" -le "$int2" | True nếu số nguyên 1 nhỏ hơn hoặc bằng số nguyên 2 |
10.1: Conditional execution của các command
Cách sử dụng thế nào? Bất kỳ command, expression hoặc function nào cũng như external command hoặc script bên ngoài nào đều có thể được executed có điều kiện sử dụng toán tử && và ||
Ví dụ, câu lệnh này chỉ in path của thư mục hiện tại nếu lệnh cd thành công.
cd my_directory && pwd
Tương tự như vậy, câu lệnh này sẽ thoát ra nếu lệnh cd không thành công, ngăn chặn những thứ không thế kiểm soát được ở phía sau =)) :
cd my_directory || exit
rm -rf *
Khi kết hợp nhiều câu lệnh theo cách này, điều quan trọng cần nhớ là (không giống như trong ngôn ngữ C) các toán tử này không có quyền ưu tiên và được left-associative
Do đó, câu lệnh này sẽ hoạt động như mong đợi ...
cd my_directory && pwd || echo "No such directory"
- Nếu cd thành công, && pwd thực thi và path thư mục làm việc hiện tại được in ra. Trừ khi pwd không thành công, cái || echo ... sẽ không được thực thi.
- Nếu cd không thành công, && pwd sẽ bị bỏ qua và dấu || echo ... sẽ chạy.
Nhưng với if...then...else thì sẽ khác nhé
Cùng xem tiếp câu lệnh tiếp theo
cd my_directory && ls || echo "No such directory"
-
Nếu cd không thành công, && ls bị bỏ qua và dấu || echo ... được thực thi.
-
Nếu cd thành công, && ls được thực thi.
-
Nếu ls thành công, || echo ... bị bỏ qua.
-
NHƯNG ... nếu ls không thành công, || echo ... cũng sẽ được thực thi.
10.2: If statement
Hãy xem một ví dụ về việc sử dụng if:
if [[ $1 -eq 1 ]]; then
echo "1 was passed in the first parameter"
elif [[ $1 -gt 2 ]]; then
echo "2 was not passed in the first parameter"
else
echo "The first parameter was not 1 and is not more than 2."
fi
Đóng fi là cần thiết, nhưng có thể bỏ qua mệnh đề elif và / hoặc các mệnh đề khác.
Dấu chấm phẩy trước đó là cú pháp tiêu chuẩn để kết hợp hai lệnh trên một dòng; chúng có thể được bỏ qua chỉ khi sau đó được chuyển sang dòng tiếp theo.
Điều quan trọng là phải hiểu rằng dấu ngoặc [[
không phải là một phần của cú pháp, nhưng được coi như một lệnh; nó là
thoát mã khỏi lệnh đang được kiểm tra này. Do đó, bạn phải luôn bao gồm các khoảng trắng xung quanh dấu ngoặc.
Điều này cũng có nghĩa là kết quả của bất kỳ lcommand nào cũng có thể được kiểm tra. Nếu exit codelà số 0, statement được coi là đúng.
if grep "foo" bar.txt; then
echo "foo was found"
else
echo "foo was not found"
fi
Các biểu thức toán học, khi được đặt bên trong dấu ngoặc kép, cũng trả về 0 hoặc 1 theo cách tương tự, và có thể cũng được kiểm tra:
if (( $1 + 5 > 91 )); then
echo "$1 is greater than 86"
fi
Bạn cũng có thể bắt gặp câu lệnh if có dấu ngoặc đơn. Chúng được định nghĩa trong tiêu chuẩn POSIX và được được đảm bảo hoạt động trong tất cả các trình bao tương thích với POSIX bao gồm cả Bash. Cú pháp rất giống với cú pháp trong Bash:
if [ "$1" -eq 1 ]; then
echo "1 was passed in the first parameter"
elif [ "$1" -gt 2 ]; then
echo "2 was not passed in the first parameter"
else
echo "The first parameter was not 1 and is not more than 2."
fi
10.3: Vòng lặp qua mảng array
Ví dụ ta có một mảng sau
arr=(a b c d e f)
Hãy thử một vài cách để duyệt các phần tử trong mảng này nhé
- For loop
for i in "${arr[@]}";do
echo "$i"
done
Hoặc
for ((i=0;i<${#arr[@]};i++));do
echo "${arr[$i]}"
done
- While loop
i=0
while [ $i -lt ${#arr[@]} ];do
echo "${arr[$i]}"
i=$(expr $i + 1)
done
hoặc
i=0
while (( $i < ${#arr[@]} ));do
echo "${arr[$i]}"
((i++))
done
10.4: Using For Loop to List Iterate Over Numbers
#! /bin/bash
for i in {1..10}; do # {1..10} expands to "1 2 3 4 5 6 7 8 9 10"
echo $i
done
Kết quả trả về sẽ là:
1
2
3
4
5
6
7
8
8
10
10.5: continue và break
Ví dụ cho continue
for i in [series]
do
command 1
command 2
if (condition) # Condition to jump over command 3
continue # skip to the next value in "series"
fi
command 3
done
Ví dụ cho break
for i in [series]
do
command 4
if (condition) # Condition to break the loop
then
command 5 # Command if the loop needs to be broken
break
fi
command 6 # Command to run if the "condition" is never true
done
10.6: Loop break
Break nhiều loop
arr=(a b c d e f)
for i in "${arr[@]}";do
echo "$i"
GoalKicker.com – Bash Notes for Professionals 38
for j in "${arr[@]}";do
echo "$j"
break 2
done
done
Output
a
a
Break chỉ 1 loop
arr=(a b c d e f)
for i in "${arr[@]}";do
echo "$i"
for j in "${arr[@]}";do
echo "$j"
break
done
done
Output
a
a
b
a
c
a
d
a
e
a
f
a
10.7: While Loop
i=0
while [ $i -lt 5 ] #While i is less than 5
do
echo "i is currently $i"
i=$[$i+1] #Not the lack of spaces around the brackets. This makes it a not a test expression
done #ends the loop
Output
i is currently 0
i is currently 1
i is currently 2
i is currently 3
i is currently 4
Chú ý các khoảng trống xung quanh dấu ngoặc trong quá trình kiểm tra (sau câu lệnh while). Những space này là cần thiết.
10.8: Until Loop
Vòng lặp Until thực thi cho đến khi điều kiện là true
i=5
until [[ i -eq 10 ]]; do #Checks if i=10
echo "i=$i" #Print the value of i
i=$((i+1)) #Increment i by 1
done
Output:
i=5
i=6
i=7
i=8
i=9
10.9: Switch case
Với case statement, bạn có thể so khớp các giá trị với một biến.
Nếu một kết quả phù hợp được tìm thấy, các lệnh được thực hiện cho đến khi gặp ;;
.
case "$BASH_VERSION" in
[34]*)
echo {1..4}
;;
*)
seq -s" " 1 4
esac
Mẫu không phải là regular expressions mà là shell pattern matching.
Kết luận
Bài viết liệt kê một số control struct mà nhiều người sẽ gắp phải hi vọng bạn đọc có thế sử dụng tốt nó trong quá trình làm việc của mình. Cảm ơn các bạn đã quan tâm đến bài viết. Link tham khảo: https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html https://books.goalkicker.com/BashBook/