第十四章、Shell 的分支结构

分支命令

分支命令是可以根据不同命令的返回结果来执行不同的命令块(命令组)的命令。

分支命令允许 Shell 程序根据条件判断来做出决策,从而实现更复杂和灵活的逻辑。

Shell 中的分支命令:

1. if 命令

if 命令用于基于条件执行不同的代码块。它是控制流程的基本结构之一,允许脚本根据测试条件的结果做出决策。

if 命令让 Shell 程序根据条件选择性的执行其中的某一个命令块。

官方语法

if COMMANDS; then COMMANDS; [ elif COMMANDS; then COMMANDS; ]... [ else COMMANDS; ] fi

上述 中括号([ ])内部的数据是可选的。后面跟 ... 说明前面的可选项可以有零次、一次或多次。if 命令可以写在一行内,也可以写在多行便于编写者阅读程序。

将上述一行整理成多行,并用中文表达需要填充的部分,即成为如下语法:

if 命令1; then
    命令块1
elif 命令2; then
    命令块2
... # 此处可以有多个 elif-then 子命令.
elif 命令n; then
    命令块n
else
    命令块(其他)
fi

if 命令的语法中,if 主命令和 elif 子命令中的 then 如果写在一行则需要再命令后面加一个 命令终止符 ;,如:if 命令1; then。如果将 then 写到下一行,则不需要在命令后加命令终止符。

即 if 语法,也可以写成

if 命令1
then
    命令块1
elif 命令2
then
    命令块2
... # 此处可以有多个 elif-then 子命令.
elif 命令n
then
    命令块n
else
    命令块(其他)
fi

这里的 命令 通常是 测试命令 test[ ])。

语法说明

  1. ifthenelifelsefi 是关键字。
  2. if - then 主命令必须存在。
  3. elif - then 是子命令,可以有0个、1个或多个。
  4. else 子命令只能有一个或者没有,且只能放在最后。
  5. fi 是 if 命令的结束标志。
  6. 命令块是由一个或多个命令组成,多个命令可以写在一行用命令终止符(;)分开,也可以写在多行内。
  7. 上述语法每行前的空格(或水平制表符)缩进仅是便于阅读代码,没有特殊含义(不同于 Python 编程语言的缩进规则)。

执行顺序说明

它自上而下通过对 then 前的命令逐个运行并检查返回值状态,直至找到一个真值,然后找到 then 后面唯一匹配的一个命令块,然后执行该命令块。

如果上述的测试命令都为假值,则执行 else 子句中的命令块(如果有 else 子句)。

示例

编写一个文件 test_if.sh,写入如下内容:

if [ -d "/home/weimingze" ]; then
    echo "存在用户主目录 /home/weimingze" > result.txt
fi

我的运行结果如下:

weimingze@mzstudio:~$ vim test_if.sh
weimingze@mzstudio:~$ bash test_if.sh
weimingze@mzstudio:~$ cat result.txt
存在用户主目录 /home/weimingze

修改文件 test_if.sh,写入如下内容:

#!/bin/bash

if [ -d "/home/wemz" ]; then
    echo "存在用户主目录 /home/weimz" > result.txt
else
    echo "不存在用户主目录 /home/weimz" > result.txt
fi

我的运行结果如下:

weimingze@mzstudio:~$ vim test_if.sh
weimingze@mzstudio:~$ bash test_if.sh
weimingze@mzstudio:~$ cat result.txt
不存在用户主目录 /home/weimz

修改文件 test_if.sh,写入如下内容:

if test -d "~/mybackup" ; then
    cp "result.txt" "~/mybackup"
    echo "备份成功: ~/mybackup"
elif [ -d "~/mydocs" ]; then
    cp "result.txt" "~/mydocs"
    echo "备份成功: ~/mydocs"
else
    echo "备份失败"
fi

我的运行结果如下:

weimingze@mzstudio:~$ ls
result.txt  test_if.sh  下载  公共  图片  文档  桌面  模板  视频  音乐
weimingze@mzstudio:~$ bash test_if.sh
备份失败

退出状态

if 命令是一条可以写成多行的命令,他的退出状态是最后执行的命令的退出状态。

练习:

写一个 Shell 脚本程序 test_score.sh 来判断学生成绩等级,并输出。

#! /bin/bash
# 输入一个 0-100 的整数,表示成绩的分数,输出等级:
# 90-100: 输出 A
# 80-89: 输出 B
# 60-79: 输出 C
# 0-59: 输出 D
# 如果输入不在 0-100 范围内,输出 "Invalid score".