shell脚本入门——流程控制

第1关:if语句

任务描述

本关任务: 掌握 if 条件判断语法及其使用方法。

相关知识

if 基本语法

if [ 条件判断式 ];then
程序
fi

或者

if [ 条件判断式 ]
  then
 程序
fi

注意事项:
(1)[ 条件判断式 ],中括号和条件判断式之间必须有空格;
(2)if 后要有空格。

if else 语法

if condition
then
    command1 
    command2
    ...
    commandN
else
    command
fi

条件判断运算符
我们在实际过程中,经常会遇到比较两个数值的大小,在数学中我们使用 > 号 ,比如 2>1 即可比较 2 和 1 的大小,那么在 shell 如何使用判断符号呢?
在 shell 中,我们使用 2 -gt 1来表达数学表达式中的 2>1, 这里 -gt表达的意思类似于数学运算符号中 >号。
shell 的测试符号也可以叫做运算符,分为三种类型:

数值测试;
字符串测试;
文件测试。
数值测试,请见下表。

参数                 说明           
-eq 等于则为真
-ne 不等于则为真
-gt 大于则为真
-ge 大于等于则为真
-lt 小于则为真
-le 小于等于则为真
【实例1】

num1=100
num2=100
if [ $num1 -eq $num2 ];then
    echo '两个数相等!'
else
    echo '两个数不相等!'
fi

我们用 -eq 测试数值是否相等。

字符串测试,请见下表。

参数                 说明           
= 等于则为真
!= 不等于则为真
-z 字符串 字符串的长度为零则为真
-n 字符串 字符串的长度不为零则为真
【实例2】判断字符串是否相等。

#!/bin/bash 
set -x
a=abc
b=cba
if [ ${a}y == ${b}y ]
then
    echo '两个字符串相等!'
else
    echo '两个字符串不相等!'
fi

显而易见输出的结果应该是“两个字符串不相等”,这里用 == 作字符串比较运算。

思考:

为什么这里判断 [ ${a}y == ${b}y ]要加个字符y了呢? 关于这一点之前教程有提过。
这里的set -x 是什么意思,请大家自己翻阅资料查看?
文件测试,请见下表。

参数                 说明           
-e 文件名 如果文件存在则为真
-r 文件名 如果文件存在且可读则为真
-w 文件名 如果文件存在且可写则为真
-x 文件名 如果文件存在且可执行则为真
-s 文件名 如果文件存在且至少有一个字符则为真
-d 文件名 如果文件存在且为目录则为真
-f 文件名 如果文件存在且为普通文件则为真
-c 文件名 如果文件存在且为字符型特殊文件则为真
-b 文件名 如果文件存在且为块特殊文件则为真
【实例3】判断 /bin 目录下是否存在 bash 文件。

cd /bin
if [ -e ./bash ];then
    echo '文件已存在!'
else
    echo '文件不存在!'
fi

if else-if else 语句
在实际生产中,我们可能遇到很多条件判断,这个时候我们就需要用到 if 语句的嵌套及 if else-if else 语法, 其语法格式如下:

if condition1 
then
    command1
elif condition2 
then 
    command2
else
    commandN

【实例4】判断两个变量是否相等:

a=10
b=20
if [ $ay == $by ]
then
   echo "a 等于 b"
elif [ $a -gt $b ]
then
   echo "a 大于 b"
elif [ $a -lt $b ]
then
   echo "a 小于 b"
else
   echo "没有符合的条件"
fi

输出结果:a 小于 b。

编程要求
在右侧代码块按照提示,完成 Begin 和end 区间代码,实现 kubernetes 集群弹性伸缩需求,具体内容如下:

判断 kubernetes 集群中当前 pod 的数量是否超过 140 个,如果超过140个,则需要 “自动增加三台集群节点”;
如果没有超过 140,但是超过或者等于 90 个 则需要“自动增加一台集群节点”;
如果没有超过 90 个,则说明“不需要增加集群节点” 。
提示:判断一个数大于 5 并且小于 10,我们需要用到复杂运算与运算,在 shell 用 &&符号表示,使用方法参考【实例5】。
【实例5】

if [ $a -gt 5 ] && [ $a -lt 10 ]; then
    echo "大于5并且小于10"
fi

&& 表示并且
|| 表示或者

测试说明

补全脚本之后,点击评测按钮,平台会对你编写的代码进行测试,当你的结果与预期输出一致时,即为通过。

开始你的任务吧,祝你成功!

Key:

#!/bin/bash

##当前pod数目 为变量current_pod_num,从后台获取,不需要修改。
current_pod_num=$1


##习题1、完成kubernetes集群弹性伸缩需求,
##--判断kubernetes集群中当前pod的数量是否超过140个;
##--如果超过140个,则需要 "自动增加三台集群节点";
#    用伪代码   echo "pod数量为$current_pod_num,自动增加三台k8s集群节点" 实现;
##--如果没有超过140,但是超过或者等于90个 则需要“自动增加一台集群节点”
#    用伪代码   echo "pod数量为$current_pod_num,自动增加一台k8s集群节点" 实现;
##--如果没有超过90个则说明“不需要增加集群节点”                        
#    用伪代码   echo "pod数量为$current_pod_num,不需要增加k8s集群节点"   实现;



##补全下面代码,请用if语句,实现习题1的需求。

##########   Begin   ##########
if [ $current_pod_num -gt 140 ] 
then 
    echo "pod数量为$current_pod_num,自动增加三台k8s集群节点"
elif [ $current_pod_num -ge 90 ] 
then 
    echo "pod数量为$current_pod_num,自动增加一台k8s集群节点"
else 
    echo "pod数量为$current_pod_num,不需要增加k8s集群节点"
fi




##########   End     ##########




第2关:case语句

任务描述

本关任务:带领大家学习 case in 语句的用法,掌握在 case in 语句中使用正则表达式的方法。

相关知识

Shell 支持两种分支结构(选择结构),分别是 if else 语句和 case in 语句。在上一关卡中,我们讲解了 if else 语句的用法,这关我们就来讲解 case in 语句。

case语法

case expression in
    pattern1)
        statement1
        ;;
    pattern2)
        statement2
        ;;
    pattern3)
        statement3
        ;;
    ……
    *)
        statementn
esac

语法说明:

case、in 和 esac 都是 Shell 关键字,expression 表示表达式,pattern 表示匹配模式;

expression 既可以是一个变量、一个数字、一个字符串,还可以是一个数学计算表达式,或者是命令的执行结果,只要能够得到 expression 的值就可以;

pattern 可以是一个数字、一个字符串,甚至是一个简单的正则表达式。

case 会将 expression 的值与 pattern1、pattern2、pattern3 逐个进行匹配:

如果 expression 和某个模式(比如 pattern2)匹配成功,就会执行这个模式(比如 pattern2)后面对应的所有语句(该语句可以有一条,也可以有多条),直到遇见双分号;;才停止;然后整个 case 语句就执行完了,程序会跳出整个 case 语句,执行 esac 后面的其它语句。
如果 expression 没有匹配到任何一个模式,那么就执行*) 后面的语句(表示其它所有值),直到遇见双分号;;或者 esac 才结束。)相当于多个 if 分支语句中最后的 else 部分。
注意:

case in 语句中的 *) 用来“托底”,万一 expression 没有匹配到任何一个模式, *) 部分可以做一些“善后”工作,或者给用户一些提示;
可以没有 *) 部分,如果 expression 没有匹配到任何一个模式,那么就不执行任何操作。
说了这么多,可能有点云里雾里,不如让我来根据【实例1】感受一下什么是case in 语句:

【实例1】根据脚本传递的第一个参数,来 echo 对应的结果。

#!/bin/bash
num=$1    # num为脚本的第一个参数
case $num in
    1)
        echo "Monday"
        ;;
    2)
        echo "Tuesday"
        ;;
    3)
        echo "Wednesday"
        ;;
    4)
        echo "Thursday"
        ;;
    5)
        echo "Friday"
        ;;
    6)
        echo "Saturday"
        ;;
    7)
        echo "Sunday"
        ;;
    *)
        echo "error"

输出结果:

当 $1=1 的时候,即匹配到 case 为 1 的条件,这时输出的结果为 Monday;

当 $1=2 的时候,按顺序匹配,先匹配 pattern1 即数值为 1,发现不匹配;继续匹配 pattern 2,发现匹配到 case 为 2 的条件,这时输出的结果为Tuesday;

以此类推,当 $1 为 3,4,5,6,7 的时候,会从上至下顺序匹配,根据匹配的条件执行对应的表达式,即输出对应的值;

当 $1 不为 1 2 3 4 5 6 7 的时候,这时会“兜底”匹配 *),执行“兜底”的语句。

case和正则表达式
case in 的 pattern 部分支持简单的正则表达式,具体来说,可以使用以下几种格式:

格式 说明

  • 表示任意字符串。
    [abc] 表示 a、b、c 三个字符中的任意一个。比如,[15ZH] 表示 1、5、Z、H 四个字符中的任意一个。
    [m-n] 表示从 m 到 n 的任意一个字符。比如,[0-9] 表示任意一个数字,[0-9a-zA-Z] 表示字母或数字。
    | 表示多重选择,类似逻辑运算中的或运算。比如,abc | xyz 表示匹配字符串 “abc” 或者 “xyz”。
    说明:

如果不加以说明,Shell 的值都是字符串,expression 和 pattern 也是按照字符串的方式来匹配的;【实例1】看起来是判断数字是否相等,其实是判断字符串是否相等;

最后一个分支*)并不是什么语法规定,它只是一个正则表达式,表示任意字符串,所以不管 expression 的值是什么,)总能匹配成功。

【实例2】:本实例演示 case in 语句中如何正则表达式。
已知脚本 a.sh 的内容如下:

#!/bin/bash
name=$1  
case $name in
    [a-zA-Z])
        echo "字母"
        ;;
    [0-9])
        echo "数字"
        ;;
        
    [educoder|github])
        echo "very good!"
        ;;
esac

我们在命令行演示输出结果如下:

[root@pre-host-work02 opt]# bash a.sh github
very good!
[root@pre-host-work02 opt]# bash a.sh educoder
very good!
[root@pre-host-work02 opt]# bash a.sh 1
数字
[root@pre-host-work02 opt]# bash a.sh 2
数字
[root@pre-host-work02 opt]# bash a.sh a
字母
[root@pre-host-work02 opt]# bash a.sh v
字母

作答要求

根据相关知识,按照要求完成右侧选择题任务。作答完毕,通过点击“测评”,可以验证答案的正确性。

开始你的任务吧,祝你成功!

Key:

在这里插入图片描述

第3关:for命令

任务描述

本关任务:掌握 for 循环语句以及 seq 命令在 for 循环中的使用。

相关知识

在实际编程中,需要重复一组命令直至达到某个特定条件,比如处理某个目录下的所有文件、系统上的所有用户或是某个文本文件中的所有行。因此诞生了 for 循环、while 循环、util 循环这样的语句。本关首先给大家介绍 for 循环语句的使用。

for循环基本语法:

for var in item1 item2 ... itemN
do
    command1
    command2
    ...
    commandN
done

或者写成一行:

for var in item1 item2 ... itemN; do command1; command2… done;

for循环语法演变:
【语法一】遍历普通列表, 在 shell 中以空格隔开的 item ,默认将其视为列表。

for 变量 in 值1 值2 值3..
  do
   程序块儿
  done

【实例1】输出五次 uptime:

#!/bin/bash 
  
for i in 1 2 3 4 5  
do  
  echo "$i-->$(uptime)" 
done

输出结果如下:

[root@master-01-k8s opt]# bash a.sh 
1--> 16:34:39 up 236 days, 23:41,  2 users,  load average: 0.53, 0.46, 0.49
2--> 16:34:39 up 236 days, 23:41,  2 users,  load average: 0.53, 0.46, 0.49
3--> 16:34:39 up 236 days, 23:41,  2 users,  load average: 0.53, 0.46, 0.49
4--> 16:34:39 up 236 days, 23:41,  2 users,  load average: 0.53, 0.46, 0.49
5--> 16:34:39 up 236 days, 23:41,  2 users,  load average: 0.53, 0.46, 0.49

【语法二】for 遍历 “命令返回结果的数组”,反引号 或者 $() 表示命令返回结果列表。

for 变量 in `命令`
  do
   程序块儿
  done

【实例2】遍历 /home 目录下的文件。

#!/bin/bash 
for i in $(ls /home)        
do
   echo "当前目录下的文件为 $i"
done

输出结果为:

当前目录下的文件为 admin
当前目录下的文件为 aliyun
当前目录下的文件为 aliyun_metric-server2.yaml
当前目录下的文件为 git
当前目录下的文件为 pdl
当前目录下的文件为 prometheus
当前目录下的文件为 work
当前目录下的文件为 zsp

【语法三】c 语言风格的循环语句:

#!/bin/bash
for (( 初始值; 循环控制; 变量变化 ))
do
  程序块儿
done

shell 的 for 命令跟 C 语言类似,有一个用来指明变量的特定方法,一个必须保持成立才能继续迭代的条件,以及另一个在每个迭代中改变变量的方法。当指定的条件不成立时, for 循环就会停止。条件等式通过标准的数学符号定义。

【实例3】

#!/bin/bash
# 注意双括号左右留有一个空格; i=1是变量赋值,不能多空格
for (( i=1; i <= 10; i++ ))  
 
do
    echo "The next number is $i"
done

这段代码产生了一个简单的迭代循环,其中变量 i 作为计数器。第一部分将一个默认值赋给该变量;中间的部分定义了循环重复的条件,当定义的条件不成立时, for 循环就停止迭代;最后一部分定义了迭代的过程。在每次迭代之后,最后一部分中定义的表达式会被执行。在本例中,i 变量会在每次迭代后增 1。
执行结果:

The next number is 1
The next number is 2
The next number is 3
The next number is 4
The next number is 5
The next number is 6
The next number is 7
The next number is 8
The next number is 9
The next number is 10

seq命令
seq 命令用于产生从某个数到另外一个数之间的所有整数列表。
常见用法如下:

seq [选项]... 尾数
seq [选项]... 首数 尾数
seq [选项]... 首数 增量 尾数

【实列4】采用 seq 命令,结合 for 循环,打印 1 到 10 之间的所有整数。

for i in `seq 1 10`
do 
    echo "第$i个数是 $i"
done

输出结果如下:

第1个数是 1
第2个数是 2
第3个数是 3
第4个数是 4
第5个数是 5
第6个数是 6
第7个数是 7
第8个数是 8
第9个数是 9
第10个数是 10

编程要求

在右侧编辑器 Begin-End 区间补充代码,使用 for 循环和 seq 命令打印 1 到 10 之间的奇数。

测试说明

补全脚本之后,点击评测按钮,平台会对你编写的代码进行测试,当你的结果与预期输出一致时,即为通过。

开始你的任务吧,祝你成功!

Key:


#!/bin/bash

##习题一
###使用for循环和seq命令打印1到10之间的奇数 
###请参考实列4

##########  Begin  ##########
for i in `seq 1 2 10`
do
    echo "1~10之间的奇数分别是:-->$i"
done


##########  End   ##########


第4关:while命令

任务描述

本关任务:掌握 while 命令的使用方法。

相关知识

三种运算符号
双小括号 (( )) 是 Bash Shell 中专门用来进行整数运算的命令,它的效率很高,写法灵活,是企业运维中常用的运算命令,具体用法请见图 1;

[]是 Shell 内置关键字,它和 test 命令类似,可用于判断某个条件是否为真。可用于字符串、数值和文件的测试;

[[ ]]是 Shell 内置关键字,它和 test 命令类似,也用来检测某个条件是否成立。相比[],[[]]功能更强大,支持正则表达式和逻辑运算。

图1

while循环语法
while 循环是 Shell 脚本中最简单的一种循环,当条件满足时,while 重复地执行一组语句;当条件不满足时,就退出 while 循环。

while 循环的用法如下:

while condition   # 此处 condition 可以是(())、[]、[[]]判断结果
do
    statements
done

语法说明: condition 表示判断条件,statements 表示要执行的语句(可以只有一条,也可以有多条),do 和 done 都是 Shell 中的关键字。

while 循环的执行流程为:

先对 condition 进行判断,如果该条件成立,就进入循环,执行 while 循环体中的语句,也就是 do 和 done 之间的语句。这样就完成了一次循环;
每一次执行到 done 的时候,都会重新判断 condition 是否成立。如果成立,就进入下一次循环,继续执行 do 和 done 之间的语句;如果不成立,就结束整个 while 循环,执行 done 后面的其它 Shell 代码;
如果一开始 condition 就不成立,那么程序就不会进入循环体,do 和 done 之间的语句就没有执行的机会。
注意:在 while 循环体中必须有相应的语句使得 condition 越来越趋近于“不成立”,只有这样才能最终退出循环,否则 while 就成了死循环,会一直执行下去,永无休止。

【实例1】每两秒钟向 /opt/uptime.log 文件中追加系统负载情况。

#!/bin/bash
while [ 1 ]   # [ 1 ]和 true 一样,只是前面2边需要有空格
do
        uptime >>/tmp/uptime.log  # >>是重定向符号
        sleep 2
done

#注:
#uptime 用于查看系统负载
#sleep 2 表示程序睡眠一秒
【实例2】计算 1+2…100 的和。

方式一:
#!/bin/sh
SUM=0
I=1
while [ $I -le 100 ]  #[]中需要变量取值符号"$",而且大于小于只能用"-le"
do
        ((SUM+=I))
        let I++
done
echo $SUM
-------------------------------------------------------------------------------------------------
方式二:
#!/bin/sh
SUM=0
I=1
while ((I<=100)) #(())中可以不要变量取值符号,大于小于是可以直接用
do
        ((SUM+=I))
        ((I++))
done
echo $SUM
-------------------------------------------------------------------------------------------------
方式三:
#!/bin/sh
SUM=0
I=100
((SUM=I*(I+1)/2))
echo $SUM

循环中断和不中断
有些程序执行时,用户希望程序一直运行。在运行【实列1】中脚本时候,我们可以使用 sh shell.sh & 来代替 sh shell.sh 让其一直在后台执行。当我们遇到脚本死循环的时候,也可以使用 Ctrl+z 的方式强制中断。
常用的中断和不中断技巧如下:

1.使用"sh shell.sh &"命令 ,即使用 & 在后台运行
2.使用"nohup shell.sh &"命令,即使用 nohup 加 & 在后台运行脚本
3.利用 screen 保持会话,然后再执行脚本,即使用 screen 保持当前会话
后台运行的知识:

sh shell.sh &        脚本 shell.sh 放在后台执行
Ctrl+c           停止执行当前脚本或任务
Ctrl+z           暂停执行当前脚本
jobs             查看当前执行的脚本或任务
bg           将当前脚本或任务放到后台执行
kill             关闭当前脚本任务,即以"kill %号码"的形式关闭进程,任务号通过 jobs 获得
fg           将当前的脚本或任务放到前台执行,若有多任务,则"fg 号码"调出相应的任务编号

【实例3】实际操作效果如下:

[centos@mycentos shell]$ sh 2.sh &  #后台运行
[1] 2988
[centos@mycentos shell]$ jobs       #查看任务数
[1]+  Running                 sh 2.sh &
[centos@mycentos shell]$ kill %1    #关闭进程为1的进程
[centos@mycentos shell]$ jobs       
[1]+  Terminated              sh 2.sh #程序已经被关闭

大家可以根据实例 3 在命令行中自己试验一下。

作答要求

根据相关知识,按照要求完成右侧选择题任务。作答完毕,通过点击“测评”,可以验证答案的正确性。

开始你的任务吧,祝你成功!

Key:

在这里插入图片描述

第5关:until命令

任务描述

本关任务:掌握 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 的控制语句,在实际生产中能够熟练使用 if 语句、while语句、for循环和 until 循环能够。本关点击评测即可通关。

开始你的任务吧,祝你成功!

Key:

##########   点击评测 , 即可通关    ##########




第6关:循环语句嵌套

任务描述

本关任务:掌握 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 的分割符为 :)

IFS=: 
for folder in $dir 
do 

现在你已经将各个目录存放在了变量 $folder 中,可以使用另一个 for 循环来迭代特定目录中的所有文件。

for file in $folder/* 
do

最后一步是检查各个文件是否具有可执行权限,你可以使用 if-then 测试功能来实现。

if [ -x $file ] 
then 
echo " $file" 
fi

测试说明
补全脚本之后,点击评测按钮,平台会对你编写的代码进行测试,当你的结果与预期输出一致时,即为通过。

开始你的任务吧,祝你成功!

Key:

#!/bin/bash 
# finding files in the dir 
dir=/usr/games
##1.修改当前shell的分割符为 :
IFS=:
 
##########  Begin  ##########
 
##2.第一个for循环,遍历$dir ,根据IFS=:指定的":"分割符隔开遍历。
for folder in $dir
do
 
##3.第二个for循环,遍历取值的变量$folder下的文件。
    for w in $folder/*
    do
 
##4.if语句判断时候具有执行权限。
        if [ -x $w ]
        then
            echo "$w"
        fi
    done
done
######### End   #########
  • 7
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一只菜鸟呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值