Skip to content

测试和判断

判断

有了测试,就要有获得测试结果的机制,并根据测试结果运行不同的代码段,这样程序就可以从简单的命令罗列变得更“智能”一些,从而实现程序的流程控制。
在 Shell 中国呢,流程控制分为两大类,一类是“循环”,一类是“判断选择”。

if 判断结构

if 是最简单的判断语句,可以针对测试结果做相应处理:如果测试为真则运行相关代码,其语法结构如下:

1
2
3
if expression; then
    command
fi

如果 expression 测试返回为真,则执行 command。
如果要执行的不止一条命令,则不同命令间用换行符隔开,如下所示:

1
2
3
4
5
if expression; then
    command1
    command2
    ...
fi

下面演示一个程序,该程序会根据输入的学生成绩打印对应的等级:
大于等于 80 分的为 A;大于等于 60 分、小于 80 分的为 B、小于 60 分的为 C

score01.sh:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
#!/bin/bash

echo -n "Please input a score:"
read SCORE

if [ "$SCORE" -lt 60 ]; then
    echo "C"
fi
if [ "$SCORE" -lt 80 -a "$SCORE" -ge 60 ]; then
    echo "B"
fi
if [ "$SCORE" -ge 80 ]; then
    echo "A"
fi
1
2
3
4
5
6
7
8
9
➜  nocilantro bash score01.sh 
Please input a score:95
A
➜  nocilantro bash score01.sh
Please input a score:75
B
➜  nocilantro bash score01.sh
Please input a score:45
C

if/else 判断结构

语法结构如下所示:

1
2
3
4
5
if expression; then
    command
else
    command
fi

使用这种结构判断某个文件是否存在的示例如下:

1
2
3
4
5
6
7
8
9
# 检查文件是否存在
#!/bin/bash

FILE=/var/log/messages
if [ -e $FILE ]; then
    echo "$FILE exists"
else
    echo "$FILE not exist"
fi

运行结果:

1
2
➜  nocilantro bash score01.sh
/var/log/messages not exist

if/elif/else 判断结构

通过if/else的语法嵌套完成多向选择,其结构如下所示:

1
2
3
4
5
6
7
8
9
if expression1; then
    command1
else
    if expression2; then
        command2
    else
        command3
    fi
fi

使用这种嵌套方式可以增加更多的选择分支,虽然从语法上来说毫无错误,但使用这种方式进入多层嵌套后,代码的可读性会变得越来越差。

例如下面的代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
#!/bin/bash

echo -n "Please input a score:"
read SCORE

if [ "$SCORE" -lt 60 ]; then
    echo "C"
else
    if [ "$SCORE" -lt 80 -a "$SCORE" -ge 60 ]; then
        echo "B"
    else
        if [ "$SCORE" -ge 80 ]; then
            echo "A"
        fi
    fi
fi

这里实现了 3 层嵌套。如果再进入更多的嵌套,会看得更加头痛。
鉴于这种原因,并不建议使用if/else进行多层嵌套,而是使用if/elif/else结构,其语法结构如下:

1
2
3
4
5
6
7
8
if expression1; then
    command1
elif expression2; then
    command2
elif expression3; then
    command3
...
fi

这种结构可根据多种情况进行处理,而且看起来结构非常清晰

下面使用if/elif/else结构来改写上面的代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
#!/bin/bash

echo -n "Please input a score:"
read SCORE

if [ "$SCORE" -lt 60 ]; then
    echo "C"
elif [ "$SCORE" -lt 80 -a "$SCORE" -ge 60 ]; then
    echo "B"
elif [ "$SCORE" -ge 80 ]; then
    echo "A"
fi