任务描述
本关任务:掌握 until 循环语句的使用。
相关知识
until语句语法
unti 循环和 while 循环恰好相反;当判断条件不成立时才进行循环,一旦判断条件成立,就终止循环。语法如下:
- until condition
- do
- statements
- done
跟 while 一样,condition 表示判断条件,statements 表示要执行的语句(可以只有一条,也可以有多条),do 和 done 都是 Shell 中的关键字。
until 循环的执行流程为:
- 先对 condition 进行判断,如果该条件不成立,就进入循环,执行 until 循环体中的语句(do 和 done 之间的语句),这样就完成了一次循环;
- 每一次执行到 done 的时候,都会重新判断 condition 是否成立。如果不成立,就进入下一次循环,继续执行循环体中的语句;如果成立,就结束整个 until 循环,执行 done 后面的其它 Shell 代码;
- 如果一开始 condition 就成立,那么程序就不会进入循环体,do 和 done 之间的语句就没有执行的机会。
注意:在 until 循环体中必须有相应的语句使得 condition 越来越趋近于“成立”,只有这样才能最终退出循环,否则 until 就成了死循环,会一直执行下去,永无休止。
【实例1】
- #!/bin/bash
- i=0
- until [[ "$i" -gt 5 ]] #大于5
- do
- let "square=i*i"
- echo "$i * $i = $square"
- let "i++"
- done
执行流程:直到 i 大于 5 的时候,循环退出;当变量 i 小于等于 5 的时候,执行 do 和 done 代码块中的命令,这里的 let 是 shell 的内置计算命令。 输入出结果如下:
- [root@work02 opt]# bash a.sh
- 0 * 0 = 0
- 1 * 1 = 1
- 2 * 2 = 4
- 3 * 3 = 9
- 4 * 4 = 16
- 5 * 5 = 25
任务描述
本关任务:掌握 shell 语句中的循环嵌套的方法和使用场景,输出系统中的可执行文件。
相关知识
循环语句可以在循环内使用任意类型的命令,包括其他循环命令。这种循环叫作嵌套循环(nested loop)。注意,在使用嵌套循环时,你是在迭代中使用迭代,与命令运行的次数是乘积关系。不注意这点的话,有可能会在脚本中造成问题。
for-for循环嵌套
这里有个在 for 循环中嵌套 for 循环的简单例子。
【实例1】
- #!/bin/bash
- # nesting for loops
- for (( a = 1; a <= 3; a++ ))
- do
- echo "Starting loop $a:"
- for (( b = 1; b <= 3; b++ ))
- do
- echo " Inside loop: $b"
- done
- done
执行脚本输出结果为:
- Starting loop 1:
- Inside loop: 1
- Inside loop: 2
- Inside loop: 3
- Starting loop 2:
- Inside loop: 1
- Inside loop: 2
- Inside loop: 3
- Starting loop 3:
- Inside loop: 1
- Inside loop: 2
- Inside loop: 3
这个被嵌套的循环(也称为内部循环,inner loop)会在外部循环的每次迭代中遍历一次它所有的值。注意,两个循环的 do 和 done 命令没有任何差别。bash shell 知道当第一个 done 命令执行时,是指内部循环而非外部循环。
for-while循环嵌套
在混用循环命令时也一样,比如在 while 循环内部放置一个 for 循环。
【实例2】
- #!/bin/bash
- # placing a for loop inside a while loop
- var1=5
- while [ $var1 -ge 0 ]
- do
- echo "Outer loop: $var1"
- for (( var2 = 1; $var2 < 3; var2++ ))
- do
- var3=$[ $var1 * $var2 ]
- echo " Inner loop: $var1 * $var2 = $var3"
- done
- var1=$[ $var1 - 1 ]
- done
执行脚本输出结果为:
- Outer loop: 5
- Inner loop: 5 * 1 = 5
- Inner loop: 5 * 2 = 10
- Outer loop: 4
- Inner loop: 4 * 1 = 4
- Inner loop: 4 * 2 = 8
- Outer loop: 3
- Inner loop: 3 * 1 = 3
- Inner loop: 3 * 2 = 6
- Outer loop: 2
- Inner loop: 2 * 1 = 2
- Inner loop: 2 * 2 = 4
- Outer loop: 1
- Inner loop: 1 * 1 = 1
- Inner loop: 1 * 2 = 2
- Outer loop: 0
- Inner loop: 0 * 1 = 0
- Inner loop: 0 * 2 = 0
until-while循环嵌套
如果真的想挑战脑力,可以混用 until 和 while 循环。 【实列3】
- #!/bin/bash
- # using until and while loops
- var1=3
- until [ $var1 -eq 0 ]
- do
- echo "Outer loop: $var1"
- var2=1
- while [ $var2 -lt 5 ]
- do
- var3=$(echo "scale=4; $var1 / $var2" | bc)
- echo " Inner loop: $var1 / $var2 = $var3"
- var2=$[ $var2 + 1 ]
- done
- var1=$[ $var1 - 1 ]
- done
执行脚本输出结果为:
- Outer loop: 3
- Inner loop: 3 / 1 = 3.0000
- Inner loop: 3 / 2 = 1.5000
- Inner loop: 3 / 3 = 1.0000
- Inner loop: 3 / 4 = .7500
- Outer loop: 2
- Inner loop: 2 / 1 = 2.0000
- Inner loop: 2 / 2 = 1.0000
- Inner loop: 2 / 3 = .6666
- Inner loop: 2 / 4 = .5000
- Outer loop: 1
- Inner loop: 1 / 1 = 1.0000
- Inner loop: 1 / 2 = .5000
- Inner loop: 1 / 3 = .3333
- Inner loop: 1 / 4 = .2500
外部的 until 循环以值 3 开始,并继续执行到值等于 0。内部 while 循环以值 1 开始并一直执行,只要值小于 5。每个循环都必须改变在测试条件中用到的值,否则循环就会无止尽进行下去。
控制循环
你可能会想,一旦启动了循环,就必须苦等到循环完成所有的迭代,并不是这样的。有两个命令能帮我们控制循环内部的情况: break 命令和 continue 命令,每个命令在如何控制循环的执行方面有不同的用法。下面将介绍如何使用这些命令来控制循环。
- break 命令:跳出单个循环在 shell 执行 break 命令时,它会尝试跳出当前正在执行的循环,请见【实例4】。
【实列4】
- #!/bin/bash
- # breaking out of a for loop
- for var1 in 1 2 3 4 5 6 7 8 9 10
- do
- if [ $var1 -eq 5 ];then
- break
- fi
- echo "Iteration number: $var1"
- done
- echo "The for loop is completed"
执行脚本输出结果为:
- Iteration number: 1
- Iteration number: 2
- Iteration number: 3
- Iteration number: 4
- The for loop is completed
for 循环通常都会遍历列表中指定的所有值。但当满足 if-then 的条件时,shell 会执行 break 命令,停止 for 循环。
- continue 命令:continue 命令可以提前中止某次循环中的命令,但并不会完全终止整个循环。可以在循环内部设置 shell 不执行命令的条件。这里有个在 for 循环中使用 continue 命令的简单例子。
【实例5】
- #!/bin/bash
- # using the continue command
- for (( var1 = 1; var1 < 15; var1++ ))
- do
- if [ $var1 -gt 5 ] && [ $var1 -lt 10 ]
- then
- continue
- fi
- echo "Iteration number: $var1"
- done
执行脚本输出结果为:
- Iteration number: 1
- Iteration number: 2
- Iteration number: 3
- Iteration number: 4
- Iteration number: 5
- Iteration number: 10
- Iteration number: 11
- Iteration number: 12
- Iteration number: 13
- Iteration number: 14
执行说明:
- 当 if-then 语句的条件被满足时(值大于 5 且小于 10),shell 会执行 continue 命令,跳过此次循环中剩余的命令,但整个循环还会继续。当 if-then 的条件不再被满足时,一切又回到正轨;
- 也可以在 while 和 until 循环中使用 continue 命令,但要特别小心。记住,当 shell 执行 continue 命令时,它会跳过剩余的命令。如果你在其中某个条件里对测试条件变量进行增值,问题就会出现。
编程要求
背景:当你从命令行中运行一个程序的时候,Linux 系统会搜索一系列目录来查找对应的文件。
在右侧编辑器 Begin-End 区间补充代码,输出变量 dir 的可执行文件有哪些。
编程思路:
- 首先是创建一个 for 循环,对环境变量 dir 中的目录进行迭代。处理的时候别忘了设置 IFS 分隔符。(
IFS=
:
,即指定 shell 的分割符为:
)
- i. IFS=:
- ii. for folder in $dir
- iii. do
- 现在你已经将各个目录存放在了变量
$folder
中,可以使用另一个 for 循环来迭代特定目录中的所有文件。
- i. for file in $folder/*
- ii. do
- 最后一步是检查各个文件是否具有可执行权限,你可以使用 if-then 测试功能来实现。
- i. if [ -x $file ]
- ii. then
- iii. echo " $file"
- iv. fi