Shell 流程控制语句


流程控制语句根据条件决定程序执行的代码块。


流程控制语句分类

Shell提供了2种类型的流程控制语句。

  • 分支语句,包含if和case语句。
  • 循环语句,包含for、while、until语句,和break、continue命令。

if语句

if语句的形式:

if 命令1; then
  命令2
elif 命令3; then
  命令4
...
else
  命令5
fi

elifelse部分都是可选的。

if语句执行过程:

执行命令1,如果执行结果为0(表示成功),则执行命令2,终止if语句。否则,执行命令3,如果执行结果为0,则执行命令4,终止if语句。如果命令1命令3的执行结果都为非0值(表示失败),则执行命令5,终止if语句。

命令返回值

shell提供了一个变量$?用来保存最后一个命令的执行结果。

#!/bin/sh
ls /etc/passwd
echo $? # 0
ls /etc/passwd2
echo $? # 1

下面是if语句的例子。

#!/bin/sh
s="1"
if [ "$s" = "" ] ; then
  echo "null str"
elif [ "$s" = "1" ] ; then
  echo "1" # 1
else
  echo "else"
fi

if [ "$s" = "" ]语句中[之后和]之前要留空格。

case语句

case语句的形式:

case 变量1 in
  模式1) 命令1;;
  模式2) 命令2;;
  ...
esac

case语句的执行过程:

使用变量1去匹配模式1,如果匹配上,则执行命令1,终止case语句。如果没匹配上,则继续匹配模式2,如果匹配上,则执行命令2,终止case语句。如果还是没匹配上,则继续匹配后面的模式。

模式例子:

  • 模式a,变量为“a”时匹配上
  • 模式*a*,变量中包含“a”时匹配上
  • 模式a|b,变量为“a”或“b”时匹配上
  • 模式*,变量为任何值都匹配上,一般做为最后一个模式,当前面所有模式都没匹配上时,执行该模式对应的命令做相应的处理。

下面是case语句的例子。

#!/bin/sh
color="ligth-gray"
case $color in
  *gray*)         echo gray;;
  *red*|*green*)  echo "red or green";;
  *blue*)         echo blue;;
  *)              echo "other color";;
esac

只要匹配上一个模式,则执行相应的命令,然后终止case语句。

for语句

for语句有两种形式:

for 变量1 [in 列表]; do
  命令
done

for (( 表达式1; 表达式2; 表达式3 )); do
  命令
done

in 列表是可选的,如果忽略,则使用位置参数(positional parameter)代替。

表达式1表达式2表达式3都是算术表达式。

第一种形式for语句执行过程:

  1. 如果列表中还有未处理的元素,从列表中,按顺序取出一个未处理的元素做为变量1的值,执行命令。如果没有未处理过的元素,终止for语句。
  2. 重复步骤2。

第二种形式for语句执行过程:

  1. 首先执行表达式1(用于初始化条件)。
  2. 执行表达式2,如果执行结果为非0值,终止for语句。否则,执行命令,然后执行表达式3(表达式3常用于增加或减少一个变量的值)。
  3. 重复步骤2。

下面是for语句的例子。

#!/bin/sh
for s in {a..c}; do
  echo $s # a b c
done
for (( i = 0; i < 3; i++ )); do
  echo $i # 0 1 2
done

while和until语句

while语句形式:

while [ 条件1 ]; do
  命令
done

until语句形式:

until [ 条件2 ]; do
  命令
done

while语句中条件1的执行结果为0(true)时才会执行命令,until语句和while语句相反,条件2的执行结果为非0(false)时才会执行命令

while语句的执行过程:

  1. 计算条件1的值,如果结果为0(true),则执行命令;如果条件1的值为非0值(false),终止while语句。
  2. 重复步骤1。

until语句的执行过程:

  1. 计算条件2的值,如果结果为非0(false),则执行命令;如果条件2的值为0值(true),终止until语句。
  2. 重复步骤2。

下面是while语句和until语句的例子。

#!/bin/sh
i=0
j=0
while [ $i -lt 3 ]; do
  echo $i
  (( i++ ))
done
until [ $j -gt 3 ]; do
  echo $j
  (( j++ ))
done

break命令

break命令用于提前终止for、while和until语句。

break命令有两种形式:breakbreak n。第一种形式break命令终止里层的循环,第二种形式break命令终止外层的循环,n指定终止循环的级数。

下面是break命令的例子。

#!/bin/sh
for s in {a..c}; do
  for i in {1..3}; do
    if [ $i -eq 2 ]; then
      break
    fi
    echo "$s$i" # a1 b1 c1
  done
done

for s in {d..f}; do
  for i in {1..3}; do
    if [ $i -eq 2 ]; then
      break 2
    fi
    echo "$s$i" # d1
  done
done

continue命令

continue命令跳过当前这次循环,进入到下次循环。

continue命令有两种形式:continuecontinue n。第一种形式continue命令跳过里层的当次循环。 第二种形式continue命令跳过外层的当次循环,n指定跳过外层的级数。

下面是continue命令的例子。

#!/bin/sh
for s in {a..c}; do
  for i in {1..3}; do
    if [ $i -eq 2 ]; then
      continue
    fi
    echo "$s$i" # a1 a3 b1 b3 c1 c3
  done
done

for s in {d..f}; do
  for i in {1..3}; do
    if [ $i -eq 2 ]; then
      continue 2
    fi
    echo "$s$i" # d1 e1 f1
  done
done