陈斌彬的技术博客

Stay foolish,stay hungry

Bash - 循环与分支

一、循环

1.for循环

for 循环一般格式为:

for 变量 in 列表
do
    command1
    command2
    ...
    commandN
done

例子:

#!/bin/bash
# 列出所有的行星名称. (译者注: 现在的太阳系行星已经有了变化^_^)

for planet in Mercury Venus Earth Mars Jupiter Saturn Uranus Neptune Pluto
do
echo $planet  # 每个行星都被单独打印在一行上.
done

echo

for planet in "Mercury Venus Earth Mars Jupiter Saturn Uranus Neptune Pluto"
# 所有的行星名称都打印在同一行上.
# 整个'list'都被双引号封成了一个变量.
do
echo $planet
done

exit 0

程序截图:

img

运行:

img

2.while循环

while 循环用于不断执行一系列命令,也用于从输入文件中读取数据;命令通常为测试条件。其格式为:

while command
do
   Statement(s) to be executed if command is true
done

命令执行完毕,控制返回循环顶部,从头开始直至测试条件为假。

#!/bin/bash

var0=0
LIMIT=10

while [ "$var0" -lt "$LIMIT" ]
do
  echo -n "$var0 "        # -n 将会阻止产生新行.
  #                     ^           空格, 数字之间的分隔.

  var0=`expr $var0 + 1`   # var0=$(($var0+1))  也可以.
  # var0=$((var0 + 1)) 也可以.
  # let "var0 += 1"    也可以.
done                      # 使用其他的方法也行.

echo

exit 0

程序截图:

img

运行:

img

3.until循环

until 循环执行一系列命令直至条件为 true 时停止。until 循环与 while 循环在处理方式上刚好相反。一般 while 循环优于 until 循环,但在某些时候,也只是极少数情况下,until 循环更加有用。

until 循环格式为:

until command
do
   Statement(s) to be executed until command is true
done

command 一般为条件表达式,如果返回值为 false,则继续执行循环体内的语句,否则跳出循环。

例如,使用 until 命令输出 0 ~ 9 的数字:

#!/bin/bash
a=0
until [ ! $a -lt 10 ]
do
   echo $a
   a=`expr $a + 1`
done    

程序截图:

img

运行:

img

二、嵌套循环

1.嵌套循环

#!/bin/bash
# nested-loop.sh: 嵌套的"for"循环.

outer=1             # 设置外部循环计数.

# 开始外部循环.
for a in 1 2 3 4 5
do
  echo "Pass $outer in outer loop."
  echo "---------------------"
  inner=1           # 重置内部循环计数.

  # ===============================================
  # 开始内部循环.
  for b in 1 2 3 4 5
  do
    echo "Pass $inner in inner loop."
    let "inner+=1"  # 增加内部循环计数.
  done
# 内部循环结束.
# ===============================================

  let "outer+=1"    # 增加外部循环的计数.
  echo              # 每次外部循环之间的间隔.
done
# 外部循环结束.

exit 0

注意: 为了能够更友好的让自己或者别人阅读和维护你的代码,应在代码中使用合理的缩进

程序截图:

img

运行:

img

三、循环控制

1.break

#!/bin/bash

LIMIT=19  # 上限

echo
echo "Printing Numbers 1 through 20 (but not 3 and 11)."

a=0

while [ "$a" -le "$LIMIT" ]
do
  a=$(($a+1))

  if [ "$a" -gt 2 ]
  then
    break  # 将会跳出整个循环.
  fi

  echo -n "$a "
done

echo; echo; echo

exit 0

程序截图:

img

运行:

img

2.continue

#!/bin/bash

LIMIT=19  # 上限

echo
echo "Printing Numbers 1 through 20 (but not 3 and 11)."

a=0

while [ $a -le "$LIMIT" ]
do
  a=$(($a+1))

  if [ "$a" -eq 3 ] || [ "$a" -eq 11 ]  # 除了3和11.
  then
    continue      # 跳过本次循环剩余的语句.
  fi

  echo -n "$a "   # 在$a等于3和11的时候,这句将不会执行.
done

echo; echo

echo Printing Numbers 1 through 20, but something happens after 2.
exit 0

程序截图:

img

运行:

img

四、测试与分支

1.case (in) / esac

case … esac 与其他语言中的 switch … case 语句类似,是一种多分支选择结构。

case 语句匹配一个值或一个模式,如果匹配成功,执行相匹配的命令。case语句格式如下:

case 值 in
模式1)
    command1
    command2
    command3
    ;;
模式2)
    command1
    command2
    command3
    ;;
*)
    command1
    command2
    command3
    ;;
esac

case工作方式如上所示。取值后面必须为关键字 in ,每一模式必须以右括号结束。取值可以为变量或常数。匹配发现取值符合某一模式后,其间所有命令开始执行直至 ;;;; 与其他语言中的 break 类似,意思是跳到整个 case 语句的最后。

取值将检测匹配的每一个模式。一旦模式匹配,则执行完匹配模式相应命令后不再继续其他模式。如果无一匹配模式,使用星号 * 捕获该值,再执行后面的命令。

下面的脚本提示输入1到4,与每一种模式进行匹配:

echo 'Input a number between 1 to 4'
echo 'Your number is:\c'
read aNum
case $aNum in
    1)  echo 'You select 1'
    ;;
    2)  echo 'You select 2'
    ;;
    3)  echo 'You select 3'
    ;;
    4)  echo 'You select 4'
    ;;
    *)  echo 'You do not select a number between 1 to 4'
    ;;
esac

img

输入不同的内容,会有不同的结果,例如:

img

2.select

select 结构是建立菜单的另一种工具,这种结构是从 ksh 中引入的。

#!/bin/bash

PS3='Choose your favorite vegetable: ' # 设置提示符字串.

echo

select vegetable in "beans" "carrots" "potatoes" "onions" "rutabagas"
do
  echo
  echo "Your favorite veggie is $vegetable."
  echo "Yuck!"
  echo
  break  # 如果这里没有 'break' 会发生什么?
done

exit 0

程序截图:

img

运行:

img