條件判斷與迴圈
部分內容由 LLM 生成,尚未經過人工驗證。
Shell 條件判斷、迴圈與流程控制。
if/elif/else 條件語句
#!/bin/bash
age=20
if [ $age -lt 18 ]; then
echo "Minor"
elif [ $age -lt 65 ]; then
echo "Adult"
else
echo "Senior"
fi單行寫法
if [ $age -ge 18 ]; then echo "Adult"; fi測試表達式
Shell 提供兩種測試語法:[ ] 和 [[ ]]
[ ] vs [[ ]]
| 特性 | [ ] | [[ ]] |
|---|---|---|
| POSIX 相容 | ✓ | ✗ (Bash/Zsh) |
| 邏輯運算 | -a, -o | &&, || |
| 模式匹配 | ✗ | ✓ |
| 正則表達式 | ✗ | ✓ |
| 變數引號 | 必須 | 可選 |
# [ ] 需要引號保護變數
if [ "$var" = "value" ]; then
echo "Match"
fi
# [[ ]] 更安全(建議使用)
if [[ $var == "value" ]]; then
echo "Match"
fi
# [[ ]] 支援模式匹配
if [[ $filename == *.txt ]]; then
echo "Text file"
fi
# [[ ]] 支援正則表達式
if [[ $email =~ ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ ]]; then
echo "Valid email"
fi檔案測試
file="test.txt"
# 檔案存在
if [[ -e $file ]]; then echo "Exists"; fi
# 是否為檔案
if [[ -f $file ]]; then echo "File"; fi
# 是否為目錄
if [[ -d $file ]]; then echo "Directory"; fi
# 是否可讀/寫/執行
if [[ -r $file ]]; then echo "Readable"; fi
if [[ -w $file ]]; then echo "Writable"; fi
if [[ -x $file ]]; then echo "Executable"; fi
# 檔案非空
if [[ -s $file ]]; then echo "Not empty"; fi數值比較
a=10
b=20
if [[ $a -eq $b ]]; then echo "Equal"; fi # 等於
if [[ $a -ne $b ]]; then echo "Not equal"; fi # 不等於
if [[ $a -lt $b ]]; then echo "Less than"; fi # 小於
if [[ $a -le $b ]]; then echo "Less or equal"; fi # 小於等於
if [[ $a -gt $b ]]; then echo "Greater"; fi # 大於
if [[ $a -ge $b ]]; then echo "Greater or equal"; fi # 大於等於字串比較
str1="hello"
str2="world"
if [[ $str1 == $str2 ]]; then echo "Equal"; fi
if [[ $str1 != $str2 ]]; then echo "Not equal"; fi
# 字串為空
if [[ -z $str1 ]]; then echo "Empty"; fi
# 字串非空
if [[ -n $str1 ]]; then echo "Not empty"; fi邏輯運算
age=25
name="Alice"
# AND
if [[ $age -ge 18 && $name == "Alice" ]]; then
echo "Adult Alice"
fi
# OR
if [[ $age -lt 18 || $age -gt 65 ]]; then
echo "Not working age"
fi
# NOT
if [[ ! -f "file.txt" ]]; then
echo "File not found"
ficase 語句
#!/bin/bash
fruit="apple"
case $fruit in
apple)
echo "Red fruit"
;;
banana)
echo "Yellow fruit"
;;
grape|cherry)
echo "Small fruit"
;;
*)
echo "Unknown fruit"
;;
esac模式匹配
case $filename in
*.txt)
echo "Text file"
;;
*.jpg|*.png)
echo "Image file"
;;
[Mm]akefile)
echo "Makefile"
;;
*)
echo "Other file"
;;
esacfor 迴圈
Range-based for
# 迭代列表
for item in apple banana cherry; do
echo "$item"
done
# 迭代檔案
for file in *.txt; do
echo "Processing $file"
done
# 迭代命令輸出
for user in $(cat /etc/passwd | cut -d: -f1); do
echo "User: $user"
done
# 迭代陣列
fruits=("apple" "banana" "cherry")
for fruit in "${fruits[@]}"; do
echo "$fruit"
doneC-style for
# 數值範圍
for ((i=0; i<10; i++)); do
echo "Number: $i"
done
# 倒數
for ((i=10; i>0; i--)); do
echo "Countdown: $i"
doneBrace Expansion
# 序列擴展
for i in {1..10}; do
echo "$i"
done
# 指定步進
for i in {0..100..10}; do
echo "$i"
done
# 字母序列
for char in {a..z}; do
echo "$char"
donewhile 迴圈
# 基本 while
count=0
while [ $count -lt 5 ]; do
echo "Count: $count"
((count++))
done
# 讀取檔案
while IFS= read -r line; do
echo "Line: $line"
done < file.txt
# 無限迴圈
while true; do
echo "Running..."
sleep 1
doneuntil 迴圈
# until 直到條件為真才停止
count=0
until [ $count -ge 5 ]; do
echo "Count: $count"
((count++))
donebreak 與 continue
# break - 跳出迴圈
for i in {1..10}; do
if [ $i -eq 5 ]; then
break
fi
echo "$i"
done
# continue - 跳過本次迭代
for i in {1..10}; do
if [ $i -eq 5 ]; then
continue
fi
echo "$i"
done
# 巢狀迴圈 break
for i in {1..3}; do
for j in {1..3}; do
if [ $j -eq 2 ]; then
break 2 # 跳出兩層迴圈
fi
echo "$i-$j"
done
done