Shell for循环语句的两种用法(非常详细,附带实例)
顾名思义,循环控制语句就是将一段代码重复执行,但并不是永远重复执行,还需要存在两个必要的因素,分别是进入循环条件和退出循环条件。
在 Shell 编程中,常用的循环控制语句有这么几种:
本节给大家介绍的是 for 循环语句,当符合进入条件时,开始进行循环操作,若在循环的过程中符合了退出条件,则整个循环结束。
如果在整个循环控制语句中只设置进入循环的条件,而没有设置退出循环的条件,那这个循环体称为死循环,说白了就是一直在循环,停不下来。
死循环并不是只有坏处,像监控服务器资源的软件中就用到了死循环,还有好多场景也用到了死循环。大家理解的死循环应该是在不该出现死循环的地方产生了死循环,这是最坏的情况,因为这会导致整个 Shell 脚本一直运行且停不下来,最终的处理方式只能通过 kill 命令将此脚本的进程强制删除。
Shell 中的 for 循环语句有两种写法,也可以理解为有两种循环方式。
在整个 for 循环结构体中,for、in、do 和 done 这 4 个关键字是永远不会变的固定格式,其中要注意的是开头使用的是 for,结尾用的是 done。
除了 4 个关键字之外,variable 表示变量,value_list 表示取值列表,value_list 在下文会详细说明。
for 循环结构体的执行逻辑:每次循环时都会先从 value_list 中取出一个值并赋给变量 variable,然后进入到循环体中,执行其中的自定义语句(statements),直到取完 value_list 中的所有值,循环就结束了。
【实例】实践 for 循环结构体的执行逻辑。
value_list 可以直接给出具体的值。在 in 关键字后面给出具体的值,多个值之间以空格分隔,示例如下:
value_list 也可以给出一个取值范围,取值范围的格式为
value_list 使用反引号
for 循环的第二种写法示例如下:
在整个 for 循环中,“i<100”表示退出条件,当这个判断条件不成立时,循环就会退出,“i++”是变量变化,使得判断条件随着每次循环逐渐变得不成立。
【实例】使用 for 循环计算从 1 到 100 相加的和。
通过刚才的流程可以总结出来,for 循环的形式一般就是:
【实例】省略初始化语句。
【实例】省略判断条件。
break 命令是 Shell 中的内置命令,跟 break 命令有同样功能的还有一个内置命令叫 continue,这两个命令均可以用来跳出循环。
【实例】省略变量变化。
因此我们在循环体内部对判断条件中变量的值进行自增、自减或其他计算方式,这样判断条件才会通过循环逐渐变得不成立,之后 for 循环才会结束。
同时省略三个表达式,这种写法本身并没有什么实际的意义,在此仅为大家做个演示。
最后简单介绍一下 break 和 continue 这两个内置命令跳出循环的用法:
【实例】分别使用 break 命令和 continue 命令跳出循环。
所以这两个内置命令虽然都是跳出循环,但是所产生的效果是不一样的,大家要根据需求和场景的不同来选择不同的跳出循环方式。
在 Shell 编程中,常用的循环控制语句有这么几种:
- for 循环控制语句;
- while 循环控制语句;
- until 循环控制语句。
本节给大家介绍的是 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 ------------------------ 循环结束后,最终的结果:21value_list 的形式有很多种,可以直接给出具体的值,也可以给出一个范围,还可以使用命令产生的结果,另外还可以使用通配符:
- 直接给出具体的值:例如,1 2 3 4 5,"abc""390""tom";
- 给出一个取值范围:{start..end},例如,{1..100},{A..Z};
- 使用命令的执行结果:例如,$(seq 2 2 100),$(ls*.sh);
- 使用Shell通配符:例如,*.sh。
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每个参数代表的含义如下:
- 初始值:定义变量的初始值。例如,i=1 表示变量 i 的初始值等于 1。
- 条件判断:例如,变量 i 的值小于等于 100,若超过则表示判断条件不成立,结果就是退出循环。
- 变量变化:很多情况下这是一个带有自增或自减运算的表达式,使循环条件随着每次循环逐渐变得不成立。
for 循环的第二种写法示例如下:
for ((i=1;i<100;i++)) do echo $i donefor 循环结构体的执行逻辑:在上述示例中,刚开始循环时,变量 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 语句时,先给变量 i 赋值为 1,然后判断 i<=100 是否成立;因为此时 i=1,所以 i<=100 成立。接下来执行循环体中的语句,循环体执行一轮后变量 sum 的值等于 1,执行自增运算“i++”。自定义语句中数学运算“((sum+=i))”的含义是“变量 sum=变量sum+变量i”。
- 到第二次循环时,i 的值因为做了自增运算所以为 2,判断条件 i<=100 成立,继续执行循环体。循环体执行结束后变量 sum 的值为 3,再执行自增运算“i++”。
- 重复执行步骤 2,直到循环至第 101 次,此时 i 的值为 101,判断条件 i<=100 不再成立,循环结束。
通过刚才的流程可以总结出来,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 命令则是提前结束本次循环,接着执行下一轮的循环。
【实例】分别使用 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通过案例可以很直观地看出两者的区别:
- continue 命令只能结束本次循环,接着执行下一轮循环,整个循环体不会结束;
- break 命令就不一样了,它会直接跳出当前整个循环,也就是整个循环体结束了。
所以这两个内置命令虽然都是跳出循环,但是所产生的效果是不一样的,大家要根据需求和场景的不同来选择不同的跳出循环方式。