09. Shell 流程控制-循环

Shell 循环结构

【09. Shell 流程控制-循环】Shell 语言和Java 等其它语言类似,也拥有for, while, until 等循环结构, 只是语法结构略微不同而已. 需要注意的是Shell 循环体是用do 和 done 限制的, 而非大括号.
1. for-each 循环
  • for-each 中直接创建的循环变量var 是全局变量,除非实现使用local 定义
  • for-each 数组或函数参数或脚本参数时,需要用引号包裹数组或$@
1.1 for-each 直接列表
for var in 1 2 3 4 5 do echo $var donefor var in "java" "linux" "java script" do echo $var done

1.2 for-each 数字区间
  • 此种循环可以设置for的步长, 但是区间表达式必须是数字直接量,不能是变量.
# 遍历1~10的数组, 变量每次加1 for var in {1..10} do sum=$(( $sum+$var )) done echo "1+2+...+10=$sum"# 遍历1~10的数组,变量每次加2 sum=0 for var in {1..10..2} do let sum=$sum+$var done echo "1+3+5+...+9=$sum"# 错误语法, 范围表达式中不能包含变量 declare -i num=10 for var in {1..$num} do echo $var done

1.3 for-each 命令
  • for-each 可以直接遍历命令结果
for line in $(cat /etc/passwd) do echo $line done

1.4 for-each 数组
  • for-each 数组时,必须使用引号包裹, 否则当数组元素中包含空格时, 会按空格做多次遍历
# 定义数组元素包含空格的数组 books=("java" "linux" "java script")# 如果不包含引号,输出为四行, 正确输出为三行 for var in "${books[@]}" do echo $var done

1.5 默认for-each 循环
  • for-each 省略循环列表时,默认遍历$@数组. 如果for循环在函数内,则遍历的是函数的参数, 否则遍历的是脚本参数.
# 以下两个方法等价 test_for(){ for var do echo $var done }test(){ for var in "$@" do echo $var done }test_for 1 2 3 4

2. 类C for循环
Shell 也有类C风格的循环, 功能强大, 使用灵活.
sum=0 for (( i=0; i<10; i++ )) do let sum=$sum+$i done echo "1+2+3+..+10=$sum"

3. while 循环
当条件测试表达式为真时, 执行循环体; 为假时,跳出循环体.
i=0 while [[ $i -le 100 ]]; do let sum=$sum+$i i=$i+1 done echo "1+2+3+...+100=$sum"

4. until 循环
当条件测试表达式为假时,执行循环体; 为真时,跳出循环体.
i=0 until [[ $i -gt 100 ]]; do let sum=$sum+$i i=$i+1 done echo "1+2+3+...+100=$sum"

5. 嵌套循环
  • continue: 跳出本次循环, 继续执行下次循环
  • break: 跳出循环体, 直接结束循环.
  • break n: 嵌套循环中,直接跳出n层循环.
# 输出九九乘法表 i=1 j=1for (( i=1; i<=9; i++ )) do for (( j=1; j<=i; j++ )) do let v=$i*$j printf "$i*$j=$v" done echo done# 输出五以内的乘法表 i=1 j=1 for (( i=1; i<=9; i++ )) do for (( j=1; j<=9; j++ )) do # 当j>i 时,结束本次循环,进行下一次循环 if [[ $j > $i ]]; then continue fi # 当i>5时,直接结束两层循环 if [[ $i > 5 ]]; then break 2 fi let v=$i*$j printf "$i*$j=$v" done echo done

    推荐阅读