Skip to content

Dashboard

Chinh phục BashShell Part 4 - Control Structures

Created by Admin

Để đế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/

Source: https://viblo.asia/p/chinh-phuc-bashshell-part-4-control-structures-Qbq5QEEX5D8