首页 > 编程笔记 > Linux笔记 阅读:187

Shell for循环语句的两种用法(非常详细,附带实例)

顾名思义,循环控制语句就是将一段代码重复执行,但并不是永远重复执行,还需要存在两个必要的因素,分别是进入循环条件和退出循环条件。

在 Shell 编程中,常用的循环控制语句有这么几种:

本节给大家介绍的是 for 循环语句,当符合进入条件时,开始进行循环操作,若在循环的过程中符合了退出条件,则整个循环结束。

如果在整个循环控制语句中只设置进入循环的条件,而没有设置退出循环的条件,那这个循环体称为死循环,说白了就是一直在循环,停不下来。

死循环并不是只有坏处,像监控服务器资源的软件中就用到了死循环,还有好多场景也用到了死循环。大家理解的死循环应该是在不该出现死循环的地方产生了死循环,这是最坏的情况,因为这会导致整个 Shell 脚本一直运行且停不下来,最终的处理方式只能通过 kill 命令将此脚本的进程强制删除。

Shell 中的 for 循环语句有两种写法,也可以理解为有两种循环方式。

Shell for循环的第一种写法

for 循环的格式如下:
for variable in value_list ; do
    statements
done
若 for 关键字与 do 在同一行则必须使用分号隔开,不在一行可以不用。

在整个 for 循环结构体中,for、in、do 和 done 这 4 个关键字是永远不会变的固定格式,其中要注意的是开头使用的是 for,结尾用的是 done。

除了 4 个关键字之外,variable 表示变量,value_list 表示取值列表,value_list 在下文会详细说明。

for 循环结构体的执行逻辑:每次循环时都会先从 value_list 中取出一个值并赋给变量 variable,然后进入到循环体中,执行其中的自定义语句(statements),直到取完 value_list 中的所有值,循环就结束了。

【实例】实践 for 循环结构体的执行逻辑。
[root@linux opt]# vim demo30.sh
#!/bin/bash
# 计算数字 1~6 相加的总和
sum=0
for n in 1 2 3 4 5 6
do
    echo "每次循环变量 n 的值:$n"
    ((sum+=n))
    echo "每次循环后的总和:$sum"
    echo "-------------------------"
done
echo "循环结束后,最终的结果:$sum"

[root@linux opt]# bash demo30.sh
每次循环变量 n 的值:1
每次循环后的总和:1
------------------------
每次循环变量 n 的值:2
每次循环后的总和:3
------------------------
每次循环变量 n 的值:3
每次循环后的总和:6
------------------------
每次循环变量 n 的值:4
每次循环后的总和:10
------------------------
每次循环变量 n 的值:5
每次循环后的总和:15
------------------------
每次循环变量 n 的值:6
每次循环后的总和:21
------------------------
循环结束后,最终的结果:21
value_list 的形式有很多种,可以直接给出具体的值,也可以给出一个范围,还可以使用命令产生的结果,另外还可以使用通配符:

seq 是一个命令,用来产生某个范围内的整数,并且可以设置步长。例如,seq 2 2 100 表示从数字 2 开始,每次增加 2,到 100 结束。


value_list 可以直接给出具体的值。在 in 关键字后面给出具体的值,多个值之间以空格分隔,示例如下:
[root@linux opt]# vim demo31.sh
#!/bin/bash

for str in "你" "看的" "教程" "zai" "c.biancheng.net" "网站" "是真的棒!"
do
    echo $str
done

[root@linux opt]# bash demo30.sh
你
看的
教程
zai
c.biancheng.net
网站
是真的棒!

value_list 也可以给出一个取值范围,取值范围的格式为{start..end},start 表示起始值,end 表示终止值(注意中间是用两个点号相连接,而不是三个点号)。一般这种方式只支持数字和字母。示例如下:
[root@linux opt]# vim demo32.sh
#!/bin/bash

# 计算从 1 加到 100 的和
sum=0
for n in {1..100}
do
    echo "每次循环变量 n 的值: $n"
    ((sum+=n))
    echo "每次循环后的总和: $sum"
    echo "-------------------------"
done
echo "循环结束后,1~100 相加的总和: " $sum

# 输出从 A 到 Z 之间的所有英文字母
echo "列出所有大写的英文字母:"
for c in {A..Z}
do
    printf "%c" $c
done
echo -e "\n"

# 输出从 a 到 z 之间的所有英文字母
echo "列出所有小写的英文字母:"
for c in {a..z}
do
    printf "%c" $c
done
echo -e "\n"

[root@linux opt]# bash demo32.sh
每次循环变量 n 的值: 1
每次循环后的总和: 1
-------------------------
每次循环变量 n 的值: 2
每次循环后的总和: 3
-------------------------
每次循环变量 n 的值: 3
每次循环后的总和: 6
-------------------------
...(省略部分内容)...
每次循环变量 n 的值: 98
每次循环后的总和: 4851
-------------------------
每次循环变量 n 的值: 99
每次循环后的总和: 4950
-------------------------
每次循环变量 n 的值: 100
每次循环后的总和: 5050
-------------------------
循环结束后,1~100 相加的总和: 5050
列出所有大写的英文字母:
ABCDEFGHIJKLMNOPQRSTUVWXYZ

列出所有小写的英文字母:
abcdefghijklmnopqrstuvwxyz

value_list 使用反引号``或者$()都可以取得命令的执行结果,示例如下:
[root@linux opt]# vim demo33.sh
#!/bin/bash

# 计算 1 ~ 100 之间所有偶数的和
sum=0
for n in $(seq 2 2 100)
do
    ((sum+=n))
done
echo "1~100 之间所有偶数的和:" $sum

# 列出当前目录下的所有 Shell 脚本文件:
echo "列出当前目录下的所有 Shell 脚本文件:"
for filename in $(ls *.sh)
do
    echo $filename
done

[root@linux opt]# bash demo33.sh
1~100 之间所有偶数的和:2550
列出当前目录下的所有 Shell 脚本文件:
demo1.sh
demo10.sh
----省略部分内容----
demo32.sh
demo33.sh

Shell for循环的第二种写法

第二种循环方式的写法:
for ((变量=初始值;条件判断;变量变化)) ; do
    statements
done
每个参数代表的含义如下:
for 循环的第二种写法示例如下:
for ((i=1;i<100;i++))
do
    echo $i
done
for 循环结构体的执行逻辑:在上述示例中,刚开始循环时,变量 i 的值等于 1,当循环一圈后,变量 i 会被加一,判断 i 是否小于 100,若小于,条件成立,循环继续,直至循环到变量 i 的值大于等于 100,这时,判断条件不成立,循环结束。

在整个 for 循环中,“i<100”表示退出条件,当这个判断条件不成立时,循环就会退出,“i++”是变量变化,使得判断条件随着每次循环逐渐变得不成立。

【实例】使用 for 循环计算从 1 到 100 相加的和。
[root@linux opt]# vim demo35.sh
#!/bin/bash
# 计算从 1 到 100 相加的和
sum=0
for ((i=1; i<=100; i++))
do
    ((sum += i))
    echo $sum
done
echo "The sum is: $sum"

[root@linux opt]# bash demo35.sh
1
3
6
...(省略部分内容)...
5050
The sum is: 5050
上述案例的脚本运行时的具体工作流程如下:
通过刚才的流程可以总结出来,for 循环的形式一般就是:
for ((初始化语句;判断条件;变量变化))
do
    自定义语句
done
初始化语句、判断条件和变量变化(自增或自减或其他计算方式)这三个表达式都是可选的,也都可以省略,但是要注意分号“;”必须保留。

【实例】省略初始化语句。
[root@linux opt]# vim demo36.sh
#!/bin/bash

sum=0
i=1
for ((; i<=100; i++))
do
    ((sum += i))
done
echo "The sum is: $sum"
[root@linux opt]# bash demo36.sh
The sum is: 5050
可以看到在本实例中,初始化语句“i=1”移到了 for 循环的外面。

【实例】省略判断条件。
[root@linux opt]# vim demo37.sh
#!/bin/bash
sum=0
for ((i=1; ; i++))
do
    if ((i>100)); then
        break
    fi
    ((sum += i))
done
echo "The sum is: $sum"
[root@linux opt]# bash demo37.sh
The sum is: 5050
没有了判断条件之后,如果不做其他处理这个 for 循环就会成为死循环,我们可以在循环体内部使用 if 命令充当判断条件,再通过 break 命令强制结束循环。

break 命令是 Shell 中的内置命令,跟 break 命令有同样功能的还有一个内置命令叫 continue,这两个命令均可以用来跳出循环。

【实例】省略变量变化。
[root@linux opt]# vim demo38.sh
#!/bin/bash
sum=0
for ((i=1; i<=100; ))
do
    ((sum += i))
    ((i++))
done
echo "The sum is: $sum"
[root@linux opt]# bash demo38.sh
The sum is: 5050
当省略了变量变化后,循环过程中就不会再对判断条件中的变量进行修改。判断条件就会一直成立,结果就是 for 循环成为死循环。

因此我们在循环体内部对判断条件中变量的值进行自增、自减或其他计算方式,这样判断条件才会通过循环逐渐变得不成立,之后 for 循环才会结束。

同时省略三个表达式,这种写法本身并没有什么实际的意义,在此仅为大家做个演示。
[root@linux opt]# vim demo39.sh
#!/bin/bash
sum=0
i=0
for ((;;))
do
    if ((i>100)); then
        break
    fi
    ((sum += i))
    ((i++))
done
echo "The sum is: $sum"
[root@linux opt]# bash demo39.sh
The sum is: 5050

最后简单介绍一下 break 和 continue 这两个内置命令跳出循环的用法:
【实例】分别使用 break 命令和 continue 命令跳出循环。
[root@linux opt]# vim demo40.sh
#!/bin/bash
# break 命令和 continue 命令之间的区别
sum=0
for ((i=1; ;i++))
do
    echo $i
    if (($i>3 && $i<7)); then
        echo "跳过"
        continue
    fi
    if (($i == 10)); then
        echo "退出"
        break
    fi
    ((sum += i))
done
echo "The sum is: $sum"

[root@linux opt]# bash demo40.sh
1
2
3
4
跳过
5
跳过
6
跳过
7
8
9
10
退出
The sum is: 30
通过案例可以很直观地看出两者的区别:
所以这两个内置命令虽然都是跳出循环,但是所产生的效果是不一样的,大家要根据需求和场景的不同来选择不同的跳出循环方式。

相关文章