8.4 条件判断式

系列 - LINUX Shell脚本

在本次实验中,我们将学习Shell脚本中的条件判断结构。首先从最基础的if…then结构开始,逐步过渡到更复杂的条件判断:if…elif和case…esac。

先看一个之前写过的脚本:

bash

#!/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语句这样改造脚本:

bash

#!/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语言中的:

c

if (条件) {
	// 语句1
} else {
	// 语句2
}

等价于 bash 中的:

bash

if [ 条件 ]; then
	# 语句1
else
	# 语句2
fi

而 C 语言中的:

c

if (条件1) {
	// 语句1
} else if (条件2) {
	// 语句2
} else {
	// 语句3
}

等价于:

bash

if [ 条件1 ]; then
	# 语句1
elif [ 条件2 ]; then
	# 语句2
else
	# 语句3
fi
信息
我们现在都比较关注还有多少天放寒假。

下面让我们通过一个实际的例子来运用多重条件判断。这个例子会计算距离放假还有多少天。

由于日期是要用相减的方式来处置,所以我们可以通过以下步骤来实现:

  1. 使用 date --date="YYYYMMDD" +%s 命令将日期转换为从1970年1月1日开始累积的秒数
  2. 将目标日期(放假日期)和当前日期都转换为秒数
  3. 两个秒数相减得到时间差
  4. 将秒数差转换为天数(除以86400,即一天的秒数)

bash

#!/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

执行结果:

学习完 if, elif 等语句后,我们看下面这个脚本,这个脚本的主要功能是:

  1. 检查用户运行脚本时输入的第一个参数($1)
  2. 如果参数是"hello",就输出问候语
  3. 如果没有输入参数(为空),就提示需要输入参数
  4. 如果输入的不是"hello",就提示只接受"hello"作为参数

bash

#!/bin/bash
# 程序功能:
#	检查第一个参数$1是否等于"hello"

if [ "$1" == "hello" ]; then
      echo "你好,最近怎么样?"
elif [ "$1" == "" ]; then
      echo "你必须输入参数,例如:{$0 某个词}"
else
      echo "唯一有效的参数是'hello',例如:{$0 hello}"
fi

该代码的流程图如下:

在学习了if条件语句后,我们来看另一种实现条件判断的方法:case语句。case语句特别适合用于多重分支的判断场景。让我们用case语句改写这个例子:

bash

#!/bin/bash
# 程序功能:
#	使用case语句检查第一个参数$1是否等于"hello"
# 这是将之前if语句的例子改写成case版本

case "$1" in
    "hello")
        echo "你好,最近怎么样?"
        ;;
    "")
        echo "你必须输入参数,例如:{$0 某个词}"
        ;;
    *)
        echo "唯一有效的参数是'hello',例如:{$0 hello}"
        ;;
esac
case语句的语法结构
  1. case 变量名 in开头
  2. 每种情况用)结尾
  3. 每个分支用;;表示结束
  4. *)表示默认情况,相当于if语句中的else
  5. 最后用esac(就是case反过来写)结束整个语句

通过对比两种实现方式,我们可以发现:

  1. case语句的结构更加清晰,特别是在处理多个条件分支时
  2. case语句的语法更简洁,不需要重复编写判断命令
  3. 代码的维护性更好,添加新的条件分支更容易
建议
在实际开发中,如果需要判断的条件超过2-3个,建议使用case语句来代替多个elif。

相关内容