Shell 条件测试与 if 语句:从基础到实战
Shell 条件测试与 if 语句:从基础到实战
在 Shell 脚本中,条件测试和 if
语句是实现逻辑判断的核心工具,能够根据不同情况执行不同命令。本文详细讲解条件测试的类型、表达式及 if
语句的用法,并通过实战案例巩固知识点。
一、条件测试类型
条件测试用于判断“整数大小”“字符串是否相等”“文件是否存在”等场景,主要分为三类:
测试类型 | 作用范围 | 核心运算符/选项 |
---|---|---|
整数测试 | 比较两个整数的大小(相等、大于、小于等) | -eq (等于)、-gt (大于)、-lt (小于)等 |
字符测试 | 检查字符串是否为空、是否相等 | == (相等)、-z (空字符串)、-n (非空字符串) |
文件测试 | 判断文件/目录的属性(存在性、类型、权限等) | -e (存在)、-f (普通文件)、-d (目录)等 |
二、条件测试的表达式
Shell 提供三种方式编写条件测试表达式,效果相同,可根据习惯选择:
表达式格式 | 语法示例 | 说明 |
---|---|---|
test 条件 | test $a -gt $b | 最原始的测试命令,兼容性好。 |
[ 条件 ] | [ $a -gt $b ] | 简化写法,[ 后和 ] 前必须有空格。 |
[[ 条件 ]] | [[ $a -gt $b ]] | Bash 扩展语法,支持模式匹配,推荐使用。 |
示例:测试文件是否存在
# 创建测试文件
[root@ansible ~]# touch file.txt# 三种方式测试文件是否存在
[root@ansible ~]# test -e file.txt && echo "存在" || echo "不存在"
存在
[root@ansible ~]# [ -e file.txt ] && echo "存在" || echo "不存在"
存在
[root@ansible ~]# [[ -e file.txt ]] && echo "存在" || echo "不存在"
存在# 测试不存在的文件
[root@ansible ~]# [[ -e nofile.txt ]] && echo "存在" || echo "不存在"
不存在
说明:
&&
表示“条件为真时执行后面命令”,||
表示“条件为假时执行后面命令”,常用于简化判断逻辑。
三、整数测试
用于比较两个整数的关系,核心运算符如下:
运算符 | 含义 | 示例(a=10 ,b=5 ) | 结果 |
---|---|---|---|
-eq | 等于 | [[ $a -eq $b ]] | 假(10≠5) |
-ne | 不等于 | [[ $a -ne $b ]] | 真(10≠5) |
-gt | 大于 | [[ $a -gt $b ]] | 真(10>5) |
-lt | 小于 | [[ $a -lt $b ]] | 假(10<5) |
-ge | 大于或等于 | [[ $a -ge 10 ]] | 真(10≥10) |
-le | 小于或等于 | [[ $b -le 5 ]] | 真(5≤5) |
实战案例:整数比较脚本
需求:接收两个参数,判断是否为整数并比较大小。
#!/bin/bash
# 脚本名:compare_num.sh
# 功能:比较两个整数的大小# 1. 检查参数数量(必须输入2个参数)
if [ $# -ne 2 ]; thenecho "错误:必须输入两个参数!"exit 1 # 非0退出表示执行失败
fi# 2. 检查参数是否为整数(通过expr计算是否报错)
expr $1 + $2 > /dev/null 2>&1 # 重定向所有输出到黑洞(不显示错误)
if [ $? -ne 0 ]; then # $? 为上一条命令的返回码,非0表示不是整数echo "错误:输入的参数必须是整数!"exit 1
fi# 3. 比较两个整数大小
num1=$1
num2=$2if [ $num1 -gt $num2 ]; thenecho "$num1 大于 $num2"
elif [ $num1 -eq $num2 ]; thenecho "$num1 等于 $num2"
elseecho "$num1 小于 $num2"
fi
执行测试
[root@ansible ~]# sh test1.sh 10 5
10 大于 5
[root@ansible ~]# sh test1.sh 5 5
5 等于 5
[root@ansible ~]# sh test1.sh 2 8
2 小于 8
[root@ansible ~]# sh test1.sh 1
错误:必须输入两个参数!
[root@ansible ~]# sh test1.sh a b
错误:输入的参数必须是整数!
四、字符测试
用于处理字符串相关的判断,核心运算符如下:
运算符 | 含义 | 示例(str1="abc" ,str2="def" ) | 结果 |
---|---|---|---|
== | 字符串相等(= 也可,推荐 == ) | [[ $str1 == $str2 ]] | 假(abc≠def) |
!= | 字符串不相等 | [[ $str1 != $str2 ]] | 真(abc≠def) |
-z "字符串" | 字符串为空(长度为0) | [[ -z "" ]] | 真(空字符串) |
-n "字符串" | 字符串非空(长度≥1) | [[ -n $str1 ]] | 真(abc非空) |
示例:字符测试脚本
[root@ansible ~]# vim test2.sh#!/bin/bash
# 脚本名:string_test.shstr1="hello"
str2="world"
empty_str=""# 测试字符串是否相等
if [[ $str1 == $str2 ]]; thenecho "$str1 和 $str2 相等"
elseecho "$str1 和 $str2 不相等" # 输出此结果
fi# 测试字符串是否为空
if [[ -z $empty_str ]]; thenecho "empty_str 是空字符串" # 输出此结果
elseecho "empty_str 不是空字符串"
fi# 测试字符串是否非空
if [[ -n $str1 ]]; thenecho "$str1 不是空字符串" # 输出此结果
elseecho "$str1 是空字符串"
fi执行脚本:
[root@ansible ~]# chmod +x test2.sh
[root@ansible ~]# ./test2.sh
hello 和 world 不相等
empty_str 是空字符串
hello 不是空字符串
五、文件测试
用于检查文件/目录的属性,是运维脚本中最常用的测试类型,核心选项如下:
选项 | 含义 | 示例(file="/tmp/test.txt" ) |
---|---|---|
-e 文件 | 文件是否存在 | [[ -e $file ]] |
-f 文件 | 是否为普通文件(非目录/设备) | [[ -f $file ]] |
-d 目录 | 是否为目录 | [[ -d /tmp ]] |
-L 文件 | 是否为符号链接文件 | [[ -L /tmp/link ]] |
-r 文件 | 当前用户是否有读权限 | [[ -r $file ]] |
-w 文件 | 当前用户是否有写权限 | [[ -w $file ]] |
-x 文件 | 当前用户是否有执行权限 | [[ -x /bin/ls ]] |
-s 文件 | 文件是否非空(大小>0) | [[ -s $file ]] |
文件1 -nt 文件2 | 文件1是否比文件2新(修改时间更新) | [[ /tmp/a -nt /tmp/b ]] |
实战案例:文件属性检查脚本
[root@ansible ~]# vim test3.sh#!/bin/bash
# 脚本名:file_check.sh
# 功能:检查指定文件的属性# 接收用户输入的文件路径
read -p "请输入要检查的文件路径:" file# 1. 检查文件是否存在
if [[ ! -e $file ]]; then # ! 表示取反echo "错误:文件 $file 不存在!"exit 1
fi# 2. 检查文件类型
if [[ -f $file ]]; thentype="普通文件"
elif [[ -d $file ]]; thentype="目录"
elif [[ -L $file ]]; thentype="符号链接"
elsetype="其他类型文件"
fi# 3. 检查权限
perm=""
[[ -r $file ]] && perm+="读"
[[ -w $file ]] && perm+="写"
[[ -x $file ]] && perm+="执行"# 4. 输出结果
echo "文件 $file 的属性:"
echo "类型:$type"
echo "权限:$perm"
echo "是否非空:$( [[ -s $file ]] && echo "是" || echo "否" )"
执行测试
[root@ansible ~]# chmod +x test3.sh# 测试普通文件
[root@ansible ~]# ./test3.sh
请输入要检查的文件路径:file
文件 file 的属性:
类型:普通文件
权限:读写
是否非空:否# 测试目录
[root@ansible ~]# ./test3.sh
请输入要检查的文件路径:/tmp
文件 /tmp 的属性:
类型:目录
权限:读写执行
是否非空:是
六、组合测试
通过逻辑运算符组合多个条件,实现复杂判断,常用逻辑运算符:
运算符 | 含义 | 等价符号 | 示例(判断 a 是 1-10 之间的整数) |
---|---|---|---|
-a | 逻辑与 | && | [[ $a -ge 1 -a $a -le 10 ]] 或 [[ $a -ge 1 && $a -le 10 ]] |
-o | 逻辑或 | ` | |
! | 逻辑非 | ! | [[ ! -e $file ]] (文件不存在) |
示例:组合条件判断
#!/bin/bash
# 检查参数是否为 1-10 之间的整数
read -p "请输入一个数字:" num# 组合条件:是整数 且 大于等于1 且 小于等于10
if [[ $num =~ ^[0-9]+$ && $num -ge 1 && $num -le 10 ]]; thenecho "$num 是 1-10 之间的整数"
elseecho "$num 不是 1-10 之间的整数"
fi
七、if 语句
if
语句根据条件测试的结果(真/假)执行不同的命令块,分为单分支、双分支和多分支三种结构。
1. 单分支 if 语句
语法:
if 条件测试; then条件为真时执行的命令
fi
案例:判断当前用户是否为 root
[root@ansible ~]# vim aa.sh#!/bin/bash
# 脚本名:check_root.shif [[ $USER != "root" ]]; thenecho "错误:必须以 root 用户执行此脚本!"exit 1
fiecho "欢迎,root 用户!"执行脚本:
[root@ansible ~]# sh aa.sh
欢迎,root 用户!
2. 双分支 if 语句
语法:
if 条件测试; then条件为真时执行的命令
else条件为假时执行的命令
fi
案例:判断文件是否存在,不存在则创建
[root@ansible ~]# vim bb.sh#!/bin/bash
# 脚本名:create_file.shfile="/tmp/auto_create.txt"if [[ -e $file ]]; thenecho "文件 $file 已存在"
elseecho "文件 $file 不存在,正在创建..."touch $fileecho "创建成功!"
fi执行脚本:
[root@ansible ~]# sh bb.sh
文件 /tmp/auto_create.txt 不存在,正在创建...
创建成功!
[root@ansible ~]# sh bb.sh
文件 /tmp/auto_create.txt 已存在
[root@ansible ~]#
3. 多分支 if 语句
语法:
if 条件1; then条件1为真时执行的命令
elif 条件2; then条件2为真时执行的命令
elif 条件3; then条件3为真时执行的命令
else所有条件都为假时执行的命令
fi
案例:根据分数评级(90-100 为 A,80-89 为 B,否则为 C)
[root@ansible ~]# vim cc.sh#!/bin/bash
# 脚本名:grade.shread -p "请输入分数(0-100):" score# 检查是否为合法分数
if ! [[ $score =~ ^[0-9]+$ && $score -ge 0 && $score -le 100 ]]; thenecho "错误:请输入 0-100 之间的整数!"exit 1
fi# 评级
if [[ $score -ge 90 ]]; thengrade="A"
elif [[ $score -ge 80 ]]; thengrade="B"
elsegrade="C"
fiecho "你的评级是:$grade"执行脚本:
[root@ansible ~]# sh cc.sh
请输入分数(0-100):101
错误:请输入 0-100 之间的整数!
[root@ansible ~]# sh cc.sh
请输入分数(0-100):80
你的评级是:B
[root@ansible ~]# sh cc.sh
请输入分数(0-100):90
你的评级是:A
[root@ansible ~]# sh cc.sh
请输入分数(0-100):60
你的评级是:C
总结
条件测试和 if
语句是 Shell 脚本实现逻辑控制的基础,核心要点:
- 测试类型:整数、字符串、文件测试覆盖了绝大多数判断场景;
- 表达式格式:推荐使用
[[ 条件 ]]
,兼容性好且支持扩展功能; - if 结构:根据需求选择单分支(简单判断)、双分支(二选一)或多分支(多选一);
- 实战技巧:结合逻辑运算符(
&&
/||
/!
)实现复杂条件,用$?
检查命令执行结果。
掌握这些内容后,可编写具有复杂逻辑的自动化脚本,如系统监控、文件管理、批量部署等。