条件判断与分支结构是 Shell 脚本实现逻辑控制的核心机制,通过对文件属性、数值大小和字符串模式的判断,可构建灵活的业务逻辑。本节将从文件测试、数值比较和模式匹配三个维度,系统解析 if-else 与 case 语句的应用场景与语法特性。
if-else 结构是实现文件属性判断的基础工具,其基本语法通过条件表达式与分支执行块的组合,实现流程控制。
if-else 核心语法结构
if [ condition ]; then
elif [ condition ]; then
else
fi
文件测试常用条件包括:-f(普通文件)、-d(目录)、-x(可执行权限)、-r(读权限)等。通过逻辑运算符(&& 逻辑与、|| 逻辑或)可实现多条件组合判断。例如,判断目标路径是否为普通文件且拥有执行权限:
target_file="/usr/local/bin/script.sh"
if [ -f "$target_file" ] && [ -x "$target_file" ]; then
echo "文件 $target_file 存在且可执行"
"$target_file" # 直接执行文件
elif [ -d "$target_file" ]; then
echo "错误:$target_file 是目录,不是可执行文件"
else
echo "错误:$target_file 不存在或不可执行"
fi
上述示例中,-f "$target_file" 验证文件类型,-x "$target_file" 验证执行权限,两者通过 && 构成“与”逻辑,确保只有同时满足时才执行文件调用。
数值比较用于判断变量与常量或变量间的大小关系,Shell 提供两种主流语法:传统 [ ] 语法与 Bash 增强 (( )) 语法,二者在符号使用与兼容性上存在显著差异。
传统 [ ] 语法依赖 -gt(大于)、-lt(小于)、-eq(等于)等关键字,变量引用需加 $ 符号,且条件表达式内外需严格空格分隔:
age=25
if [ $age -ge 18 ] && [ $age -lt 60 ]; then
echo "年龄 $age,处于成年阶段"
fi
Bash 增强 (( )) 语法支持直接使用 >、<、== 等数学运算符,变量引用可省略 $ 符号,语法更接近常规编程语言:
count=15
if (( count > 10 )) && (( count % 2 == 0 )); then
echo "计数 $count 满足:大于 10 且为偶数"
fi
两种语法的核心差异如下表所示:
| 特性 | [ ] 语法 | (( )) 语法 |
|---|---|---|
| 比较符号 | -gt(大于)、-lt(小于)等 |
>(大于)、<(小于)等 |
| 变量引用 | 必须加 $(如 $num) |
可省略 $(如 num) |
| 空格要求 | 条件内外需空格(如 [ $a -gt $b ]) |
可省略空格(如 ((a>b))) |
| 逻辑运算符 | -a(与)、-o(或) |
&&(与)、` |
| 兼容性 | 兼容所有 POSIX Shell | 仅支持 Bash/Korn Shell |
最佳实践:编写跨平台脚本时优先使用 [ ] 语法以确保兼容性;若明确基于 Bash 环境开发,(( )) 语法因其直观性更适合复杂数值运算场景。
case 语句专为多模式匹配设计,通过模式字符串与目标变量的比对,实现分支选择,尤其适用于命令行参数解析与菜单交互场景。其基本语法如下:
case 语句结构
case "$variable" in
pattern1)
;;
pattern2|pattern3)
;;
*)
;;
esac
以命令行参数解析为例,通过 case 语句可简洁处理 -h/--help、-v/--version 等常见选项:
#!/bin/bash
case "$1" in
-h|--help)
echo "Usage: $(basename "$0") [OPTION]"
echo "Options:"
echo " -h, --help Show this help message"
echo " -v, --version Show version information"
exit 0
;;
-v|--version)
echo "$(basename "$0") 1.0.0"
exit 0
;;
*)
echo "Error: Unknown option '$1'" >&2
echo "Try '$0 -h' for more information." >&2
exit 1
;;
esac
上述示例中,-h|--help 通过 | 实现多模式匹配,避免了 if-elif 结构的重复判断;*) 作为默认分支捕获未知参数,确保脚本鲁棒性。相较于嵌套 if-elif,case 语句在处理 3 个以上分支时,可将代码复杂度从 O(n) 降至 O(1),显著提升可读性与维护性。
条件判断与分支结构是 Shell 脚本逻辑控制的基石:文件测试通过 if-else 与逻辑运算符组合,实现文件属性的精确验证;数值比较需根据兼容性需求选择 [ ] 或 (( )) 语法;模式匹配则依托 case 语句的多模式特性,高效处理参数解析与菜单交互。实际开发中,需结合场景灵活选择语法,并通过变量引号(如 "$file")避免路径含空格等边界情况引发的错误。