0%

流程控制

Shell 流程控制:if 条件判断与 case 分支语句

流程控制是 Shell 脚本的核心功能,通过 ifcase 语句可以实现根据不同条件执行不同命令的逻辑。本文将详细讲解这两种语句的语法、用法及注意事项。

if 条件判断语句

if 语句通过判断条件的真假来执行不同的命令块,支持单分支、双分支和多分支结构。

基本语法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 单分支
if 条件
then
命令1
命令2
fi

# 双分支
if 条件
then
条件为真时执行
else
条件为假时执行
fi

# 多分支
if 条件1
then
条件1为真时执行
elif 条件2
then
条件2为真时执行
else
所有条件都为假时执行
fi

注意

  • then 可以和 if 写在同一行,用分号分隔:if 条件; then
  • 语句块必须以 fiif 的反写)结束。

条件表达式的写法

Shell 中条件判断主要通过 test 命令或方括号 [] 实现,两者功能完全相同。

(1)数值比较
运算符 含义 示例
-eq 等于 [ $a -eq $b ]
-ne 不等于 [ $a -ne $b ]
-gt 大于 [ $a -gt $b ]
-lt 小于 [ $a -lt $b ]
-ge 大于等于 [ $a -ge $b ]
-le 小于等于 [ $a -le $b ]

示例

1
2
3
4
5
6
7
8
9
10
a=10
b=20

if [ $a -lt $b ]
then
echo "$a 小于 $b"
else
echo "$a 不小于 $b"
fi
# 输出:10 小于 20
(2)字符串比较
运算符 含义 示例
= 等于(注意不是 ==,部分 Shell 兼容但不推荐) [ "$str1" = "$str2" ]
!= 不等于 [ "$str1" != "$str2" ]
-z 字符串长度为 0 [ -z "$str" ]
-n 字符串长度不为 0 [ -n "$str" ]

示例

1
2
3
4
5
6
7
8
9
name="Shell"

if [ "$name" = "Shell" ]
then
echo "名称正确"
else
echo "名称错误"
fi
# 输出:名称正确

注意:字符串变量必须用双引号包裹,避免空值导致语法错误。

(3)文件判断
运算符 含义 示例
-f 是否为普通文件 [ -f "file.txt" ]
-d 是否为目录 [ -d "dir" ]
-e 文件或目录是否存在 [ -e "path" ]
-r 是否有读权限 [ -r "file.txt" ]
-w 是否有写权限 [ -w "file.txt" ]
-x 是否有执行权限 [ -x "script.sh" ]

示例

1
2
3
4
5
6
7
8
9
file="test.sh"

if [ -f "$file" ] && [ -x "$file" ]
then
echo "$file 是可执行文件,正在运行..."
./$file
else
echo "$file 不存在或不可执行"
fi

逻辑运算符

多条件判断可使用逻辑运算符:

  • &&:逻辑与(条件都为真才成立)
  • ||:逻辑或(至少一个条件为真)
  • !:逻辑非(取反)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
age=25

# 逻辑与:年龄大于18且小于30
if [ $age -gt 18 ] && [ $age -lt 30 ]
then
echo "青年"
fi

# 逻辑或:年龄小于18或大于60
if [ $age -lt 18 ] || [ $age -gt 60 ]
then
echo "非青壮年"
else
echo "青壮年"
fi

case 分支语句

case 语句适用于多值匹配场景,通过匹配变量与不同模式,执行对应的命令块,比多分支 if 语句更简洁。

基本语法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
case 变量 in
模式1)
命令1
命令2
;; # 结束当前分支
模式2)
命令3
;;
模式3|模式4) # 匹配模式3或模式4
命令4
;;
*) # 匹配所有未被上述模式匹配的情况(默认分支)
命令5
;;
esac # 结束case语句

注意

  • 每个模式必须以 ) 结尾
  • 每个分支必须以 ;; 结束(类似其他语言的 break
  • * 表示默认模式,通常放在最后

模式匹配规则

case 支持通配符匹配:

  • *:匹配任意长度的任意字符(如 a* 匹配以 a 开头的字符串)
  • ?:匹配任意单个字符(如 a? 匹配 abac 等)
  • [abc]:匹配 abc 中的任意一个(如 [0-9] 匹配数字)
  • |:匹配多个模式中的一个(如 a|b 匹配 ab

示例

(1)简单匹配
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
echo "请输入数字(1-3):"
read num

case $num in
1)
echo "你选择了 1"
;;
2)
echo "你选择了 2"
;;
3)
echo "你选择了 3"
;;
*)
echo "输入错误,只能输入1-3"
;;
esac
(2)通配符匹配
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
echo "请输入一个字符:"
read char

case $char in
[a-z])
echo "你输入了小写字母"
;;
[A-Z])
echo "你输入了大写字母"
;;
[0-9])
echo "你输入了数字"
;;
*)
echo "你输入了特殊字符"
;;
esac
(3)多模式匹配
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
echo "请输入操作(start/stop/restart):"
read action

case $action in
start|begin) # 匹配 start 或 begin
echo "启动服务..."
;;
stop|end) # 匹配 stop 或 end
echo "停止服务..."
;;
restart|reload)
echo "重启服务..."
;;
*)
echo "无效操作"
;;
esac

常见错误与注意事项

  1. 方括号的空格[] 前后必须有空格,如 [ $a -eq $b ] 正确,[$a -eq $b] 错误。
  2. 变量引用:字符串变量和可能为空的变量必须用双引号包裹,避免语法错误。
  3. 分号和双分号ifthen 前的分号、case 中的 ;; 不能省略。
  4. 模式顺序case 中模式匹配从上到下,找到第一个匹配项后就会退出,因此更具体的模式应放在前面,* 放在最后。

欢迎关注我的其它发布渠道

表情 | 预览
快来做第一个评论的人吧~
Powered By Valine
v1.3.10