8.4 条件判断式

系列 - LINUX Shell脚本
目录
在本次实验中,我们将学习Shell脚本中的条件判断结构。首先从最基础的if…then结构开始,逐步过渡到更复杂的条件判断:if…elif和case…esac。
任务一:使用if…then…
先看一个之前写过的脚本:
#!/bin/bash
# Program: continue.sh
# 提示用户输入
read -p "请输入Y继续程序或输入N停止程序:" yorn
# 判断输入是否为Y/y
[ "${yorn}" == "Y" -o "${yorn}" == "y" ] && echo "程序继续运行" && exit 0
# 判断输入是否为N/n
[ "${yorn}" == "N" -o "${yorn}" == "n" ] && echo "程序停止" && exit 1
# 如果都不是,显示未知选项
echo "未知选项" && exit 2
上面脚本实现的功能是:如果用户输入Y或y,提示用户并退出;如果用户输入N或n,提示用户并异常退出,如果是其他情况,也会异常退出。
我们可以用if
语句这样改造脚本:
#!/bin/bash
# 脚本名:sh06.sh
# 提示用户输入
read -p "请输入Y继续程序或N停止程序:" yorn
# 判断输入是否为Y/y
if [ "$yorn" == "Y" ] || [ "$yorn" == "y" ]; then
echo "程序继续运行"
exit 0
fi
# 判断输入是否为N/n
if [ "$yorn" == "N" ] || [ "$yorn" == "n" ]; then
echo "程序停止"
exit 1
fi
# 如果都不是,显示未知选项
echo "未知选项" && exit 2
[ "$yorn" == "Y" ] || [ "$yorn" == "y" ]
等价于[ "$yorn" == "Y" -o "$yorn" == "y" ]
同学们可以按照喜好自由选择
通过对比这两种写法,我们可以看到if语句能让代码结构更加清晰,逻辑更易理解。虽然功能相同,但if语句的可读性明显更好。
任务二:多重、复杂条件判断
掌握了基本的if结构后,让我们来看看如何处理多个条件的情况。首先通过与大家熟悉的C语言对比来理解Shell中的多重条件语句结构。
C语言中的:
if (条件) {
// 语句1
} else {
// 语句2
}
等价于 bash 中的:
if [ 条件 ]; then
# 语句1
else
# 语句2
fi
而 C 语言中的:
if (条件1) {
// 语句1
} else if (条件2) {
// 语句2
} else {
// 语句3
}
等价于:
if [ 条件1 ]; then
# 语句1
elif [ 条件2 ]; then
# 语句2
else
# 语句3
fi
案例:假期倒计时
信息
我们现在都比较关注还有多少天放寒假。
下面让我们通过一个实际的例子来运用多重条件判断。这个例子会计算距离放假还有多少天。
由于日期是要用相减的方式来处置,所以我们可以通过以下步骤来实现:
- 使用
date --date="YYYYMMDD" +%s
命令将日期转换为从1970年1月1日开始累积的秒数 - 将目标日期(放假日期)和当前日期都转换为秒数
- 两个秒数相减得到时间差
- 将秒数差转换为天数(除以86400,即一天的秒数)
#!/bin/bash
# 脚本名:holiday_countdown.sh
# 功能:计算距离放假还有多少天
# 提示用户输入放假日期
echo "请输入放假日期 (格式为YYYYMMDD,例如20240101):"
read holiday_date
# 获取当前日期的秒数(从1970-01-01开始计算)
current_seconds=$(date +%s)
# 获取放假日期的秒数
holiday_seconds=$(date --date="$holiday_date" +%s)
# 计算两个日期相差的秒数
diff_seconds=$((holiday_seconds - current_seconds))
# 将秒数转换为天数(一天有86400秒)
diff_days=$((diff_seconds / 86400))
# 判断并显示结果
if [ $diff_days -lt 0 ]; then
echo "输入的日期已经过去了!"
elif [ $diff_days -eq 0 ]; then
echo "今天就是放假日期!"
else
echo "距离放假还有 $diff_days 天"
fi
执行结果:
任务三:case…esac语句
学习完 if, elif 等语句后,我们看下面这个脚本,这个脚本的主要功能是:
- 检查用户运行脚本时输入的第一个参数($1)
- 如果参数是"hello",就输出问候语
- 如果没有输入参数(为空),就提示需要输入参数
- 如果输入的不是"hello",就提示只接受"hello"作为参数
#!/bin/bash
# 程序功能:
# 检查第一个参数$1是否等于"hello"
if [ "$1" == "hello" ]; then
echo "你好,最近怎么样?"
elif [ "$1" == "" ]; then
echo "你必须输入参数,例如:{$0 某个词}"
else
echo "唯一有效的参数是'hello',例如:{$0 hello}"
fi
该代码的流程图如下:
在学习了if条件语句后,我们来看另一种实现条件判断的方法:case语句。case语句特别适合用于多重分支的判断场景。让我们用case语句改写这个例子:
#!/bin/bash
# 程序功能:
# 使用case语句检查第一个参数$1是否等于"hello"
# 这是将之前if语句的例子改写成case版本
case "$1" in
"hello")
echo "你好,最近怎么样?"
;;
"")
echo "你必须输入参数,例如:{$0 某个词}"
;;
*)
echo "唯一有效的参数是'hello',例如:{$0 hello}"
;;
esac
case语句的语法结构
- 以
case 变量名 in
开头 - 每种情况用
)
结尾 - 每个分支用
;;
表示结束 *)
表示默认情况,相当于if语句中的else- 最后用
esac
(就是case反过来写)结束整个语句
通过对比两种实现方式,我们可以发现:
- case语句的结构更加清晰,特别是在处理多个条件分支时
- case语句的语法更简洁,不需要重复编写判断命令
- 代码的维护性更好,添加新的条件分支更容易
建议
在实际开发中,如果需要判断的条件超过2-3个,建议使用case语句来代替多个elif。