3.条件判断和循环
条件判断
条件判断语句通常使用 if、elif(可选)、else 和 fi 关键字。
基本结构
语法:
if [ condition ]; then
# 执行当条件为真时的代码
elif [ another_condition ]; then
# 执行当另一条件为真时的代码
else
# 执行当所有条件都不为真时的代码
fi
数值比较
-eq:等于-ne:不等于-gt:大于-lt:小于-ge:大于等于-le:小于等于
# 等于
if [ "$a" -eq "$b" ]; then
echo "$a 等于 $b"
fi
# 不等于
if [ "$a" -ne "$b" ]; then
echo "$a 不等于 $b"
fi
# 大于
if [ "$a" -gt "$b" ]; then
echo "$a 大于 $b"
fi
# 小于
if [ "$a" -lt "$b" ]; then
echo "$a 小于 $b"
fi
# 大于等于
if [ "$a" -ge "$b" ]; then
echo "$a 大于等于 $b"
fi
# 小于等于
if [ "$a" -le "$b" ]; then
echo "$a 小于等于 $b"
fi
Shell 也支持使用算术表达式进行数值比较。可以使用常见的算术运算符(+、-、*、/ 等)进行比较。算术表达式更灵活,适用于复杂的数值计算和比较。
使用双括号 ((...))
a=5
b=10
if ((a > b)); then
echo "$a 大于 $b"
fi
# 或者
if ((a == b)); then
echo "$a 等于 $b"
fi
使用 let 命令
a=5
b=10
let "result = a + b"
if [ "$result" -gt 10 ]; then
echo "结果大于 10"
fi
注意:
使用双括号或
let时,不需要在变量名和运算符之间使用$符号。这是因为双括号和let都会直接解析变量名。然而,在条件测试中,使用方括号[ ]时,需要使用$符号引用变量。
字符串比较
==或=:字符串相等- 这两种形式都用于检查两个字符串是否相等。
-z:字符串是否为空- 该条件检查字符串是否为空,即字符串长度是否为零。
-n:字符串是否非空
# 等于
if [ "$str1" = "$str2" ]; then
echo "$str1 等于 $str2"
fi
# 不等于
if [ "$str1" != "$str2" ]; then
echo "$str1 不等于 $str2"
fi
# 检查字符串是否为空
if [ -z "$str" ]; then
echo "字符串为空"
fi
# 检查字符串是否非空
if [ -n "$str" ]; then
echo "字符串非空"
fi
文件比较
-
-e:文件是否存在- 这个条件用于检查指定路径的文件或目录是否存在。
-
-d:文件是否为目录 -
-f:文件是否为普通文件- 这个条件检查指定路径是否为普通文件(不是目录、设备文件等)。
-
-L:文件是否为符号链接 -
-r:文件是否可读 -
-w:文件是否可写 -
-x:文件是否可执行 -
-s:文件是否是空文件- 该条件检查文件是否为空,即文件的大小是否大于零。
# 检查文件是否存在
if [ -e "$file" ]; then
echo "文件存在"
fi
# 检查文件是否为目录
if [ -d "$dir" ]; then
echo "是目录"
fi
# 检查文件是否为普通文件
if [ -f "$file" ]; then
echo "是普通文件"
fi
逻辑运算
# 与运算
if [ "$a" -eq 1 ] && [ "$b" -eq 2 ]; then
echo "条件为真"
fi
# 或运算
if [ "$a" -eq 1 ] || [ "$b" -eq 2 ]; then
echo "条件为真"
fi
# 非运算
if ! [ "$a" -eq 1 ]; then
echo "条件为真"
fi
case
case 语句用于实现多条件的分支选择,类似于其他编程语言中的 switch 语句。
语法:
case expression in
pattern1)
# 当 expression 匹配 pattern1 时执行的代码
;;
pattern2)
# 当 expression 匹配 pattern2 时执行的代码
;;
pattern3|pattern4)
# 当 expression 匹配 pattern3 或 pattern4 时执行的代码
;;
*)
# 如果 expression 与所有 pattern 都不匹配时执行的代码
;;
esac
xpression是要匹配的表达式。pattern1,pattern2, ... 是用于匹配expression的模式。*)是一个通配模式,用于匹配所有未在之前列出的模式。
每个模式结束后,都要使用 ;; 表示一个分支的结束。
示例:
#!/bin/bash
fruit="apple"
case $fruit in
"apple")
echo "It's a tasty apple."
;;
"banana" | "orange")
echo "It's a banana or an orange."
;;
"grape")
echo "It's a juicy grape."
;;
*)
echo "It's something else."
;;
esac
根据变量 fruit 的值,case 语句匹配相应的模式执行相应的代码块。
注意:
在每个模式块结束时,使用
;;表示该分支的结束。最后一个分支的结束不需要
;;,但是为了良好的习惯,可以加上。
循环
for 循环
for 循环用于按照一定的规则迭代处理一系列元素。
语法:
for variable in [list]
do
# 在这里执行循环体的代码,可以使用 $variable 引用当前元素
done
list 可以是一个具体的元素列表,也可以是通过命令生成的元素列表。
示例1:
# 遍历固定列表
fruits=("apple" "banana" "cherry")
for fruit in "${fruits[@]}"
do
echo "Fruit: $fruit"
done
# 使用for循环遍历字符串列表
echo "遍历字符串列表:"
for fruit in apple banana cherry
do
echo "Fruit: $fruit"
done
# 遍历数字范围
for i in {1..5}
do
echo "Number: $i"
done
# 使用命令生成列表
for file in $(ls *.txt)
do
echo "Processing file: $file"
done
# 使用for循环遍历文件列表
echo "遍历文件列表:"
for file in *.txt
do
echo "File: $file"
done
示例2:
使用 read命令来逐字符读取键盘输入,并使用循环来遍历输出每一个字符。
#!/bin/bash
echo "请输入一串字符:"
read input_string
echo "你输入的字符是:"
# 使用循环逐字符输出
for (( i=0; i<${#input_string}; i++ )); do
echo "${input_string:i:1}"
done
while 循环
while 循环用于在条件为真的情况下重复执行一段代码。循环会一直执行,直到 condition 不再为真。
语法:
while [ condition ]
do
# 在这里执行循环体的代码
done
示例:
# 使用 while 循环计数
counter=1
while [ $counter -le 5 ]
do
echo "Count: $counter"
((counter++))
done
# 从文件中读取行
while IFS= read -r line
do
echo "Line: $line"
done < "file.txt"
中断循环
break
break 关键字用于中断循环的执行,跳出循环体,不再继续执行下面的代码。通常,break 语句会根据某个条件的满足性而触发。
语法:
#while中使用
while [ condition ]
do
# 在这里执行循环体的代码
if [ some_condition ]; then
break # 中断循环
fi
done
#for中使用
for variable in [list]
do
# 在这里执行循环体的代码
if [ some_condition ]; then
break # 中断循环
fi
done
示例:
# 使用 break 在循环中查找并打印第一个质数
for num in {2..20}
do
is_prime=true
for ((i=2; i<num; i++))
do
if [ $((num % i)) -eq 0 ]; then
is_prime=false
break
fi
done
if $is_prime; then
echo "First prime number: $num"
break
fi
done
continue
continue 关键字用于跳过当前循环的剩余代码,直接进入下一轮循环。
语法:
#while中使用
while [ condition ]
do
# 在这里执行循环体的代码
if [ some_condition ]; then
continue # 跳过当前循环的剩余代码,进入下一轮循环
fi
done
#for中使用
for variable in [list]
do
# 在这里执行循环体的代码
if [ some_condition ]; then
continue # 跳过当前循环的剩余代码,进入下一轮循环
fi
done
示例:
# 使用 continue 打印 1 到 10 之间的奇数
for ((i=1; i<=10; i++))
do
if [ $((i % 2)) -eq 0 ]; then
continue
fi
echo "Odd number: $i"
done
continue 会跳过后续的代码,直接进入下一轮循环。