zoukankan      html  css  js  c++  java
  • shell编程 12 --- 循环控制及状态返回值(break、continue、exit、return)

    shell 12 --- 循环控制及状态返回值(break、continue、exit、return)


    本文介绍几个特殊的命令:

    break(循环控制)、continue(循环控制)、exit(退出脚本)、return(退出函数)。


    12.1 break、continue、exit、return的区别和对比


    在上述命令中,break、continue在条件语句及循环语句(for、while、if等)中用于控制程序的走向;

    而exit则用于终止所有语句并退出当前脚本,除此之外,exit还可以返回上一次程序或命令的执行状态值给当前Shell;

    return类似于exit,只不过return仅用于在函数内部返回函数执行的状态值。


    关于这几个命令的基本说明如表12-1所示。

    命令 说明
    break n 如果省略n,则表示跳出整个循环,n便是跳出循环的层数
    continue n 如果省略n,则表示跳过本次循环,忽略本次循环的剩余代码
    进入循环的提一次循环。n表示退到第几层继续循环
    exit n 退出当前shell程序,n为上一次程序执行的状态返回值。
    n也可以省略,在下一个shell例可通过"$?"接收exit n的返回值
    return n 用于在函数里作为函数的返回值,以判断函数执行是否正确。
    在下一个shell里可通过"$?"接收return n的值

    12.2 break、continue、exit功能执行流程图


    为了更清晰地了解上述命令的区别,下面特别画了逻辑图,方便大家理解。

    这里以while循环和for循环为例来说明。


    12.2.1 break功能的执行流程逻辑图

    在循环中break功能的执行流程逻辑图如图12-1所示。

    12.2.2 continue功能的执行流程逻辑图

    在循环中continue功能的执行流程逻辑图如图12-2所示。

    12.2.3 exit功能的执行流程逻辑图

    在循环中exit功能的执行流程逻辑图如图12-3所示。

    12.3 break、continue、exit、return命令的基础示例

    下面是与break、continue、exit、return相关的示例。

    [root@zabbix 0513]# cat test.sh 
    #!/bin/bash
    if [ $# -ne 1 ];then
        echo $"usage: $0 {break|continue|exit|return}"
        exit 1
    fi
    function test(){
        for((i=0;i<=5;i++))
        do
    	if [ $i -eq 3 ];then
    	    $*;
    	fi
    	echo $i
        done
        echo "I am in func"
    }
    test $*
    func_ret=$?
    if [ `echo $*|grep return|wc -l` -eq 1 ];then
        echo "return's exit status: $func_ret"
    fi
    echo "OK"
    

    12.3.1 break功能测试说明

    传入break执行结果:

    [root@zabbix 0513]# sh test.sh break
    0
    1
    2
    I am in func     === 传入break时,退出test函数,继续顺序执行test函数以下的
    OK
    

    说明:


    根据结果可以看到,i等于3及以后的循环没有被执行,但循环外的echo执行了,
    执行到break时跳出了if及外层的for循环语句,然后执行for循环外部done后面的打印ok的语句。


    12.3.2 continue功能测试说明

    [root@zabbix 0513]# sh test.sh continue
    0
    1
    2	===下面没有3,直接跳过了
    4
    5
    I am in func
    OK
    

    说明:


    可以看到,只有i等于3这层循环没有被执行,其他循环全部执行了,
    循环外的echo也执行了,说明执行到continue时,终止了本次循环,
    而继续下一次的循环,直到循环正常结束,接着继续执行了循环外面的所有语句。


    12.3.3 exit功能测试说明

    传入exit 119命令的执行结果为:

    [root@zabbix 0513]# sh break.sh "exit 119"
    0
    1
    2  === 直接退出shell
    [root@zabbix 0513]# echo $?
    119  === 返回了119,即传入的值
    

    说明:


    当进入循环里的if语句后遇到"exit 119"时,立刻退出程序,不但循环体3后面的数字没有输出,
    而且for循环体done外的echo和函数外的ok也没有输出,就直接退出了程序。
    另外,因为程序退出时指定了119, 所以执行脚本后获取"$?"的返回值时,
    就返回了"exit 119"后面的119这个数字到当前的Shell。


    12.3.4 return功能测试说明

    传入"return 119"命令的执行结果为:

    [root@zabbix 0513]# sh break.sh "return 119"
    0
    1
    2
    return's exit status: 119
    OK
    

    说明:


    当进入循环里的if语句后遇到return 119,就没有打印3以下的数字,
    说明return跳出了循环体,程序也没有执行for循环体done外的echo命令,
    而是直接执行了函数test外的if语句及打印ok的命令,可见return的作用是退出当前函数。
    同时,return将数字119作为函数的执行状态值返还给函数体外,
    执行脚本后打印返回值是0,因为程序的最后一行是打印ok的命令,执行是成功的。


    12.4 循环控制及状态返回值企业案例

    范例12-2:开发Shell脚本实现为服务器临时配置多个IP,并且可以随时撤销配置的所有IP。
    IP的地址范围为:10.0.2.1~10.0.2.16,其中10.0.2.10不能配置。


    本题主要用于考察continue、return、exit的综合应用,请读者细细品味。

    首先,给网卡配置额外的IP。以下介绍两种配置IP的命令(ifconfig/ip)。


    12.4.1 临时配置多个ip的方法

    1)使用ifconfig配置别名IP的方法:

    ifconfig eth0:0 10.0.0.10/24 up			==> 添加ip
    ifconfig eth0:0 10.0.0.10/24 down		==> 删除ip
    

    2)使用IP配置辅助IP的方法:

    ip addr add 10.0.0.12 dev eth0 lable eth0:0
    ip addr del 10.0.0.12 dev eth0 lable eth0:0
    

    3)然后批量配置IP。

    要求IP地址的取值范围为:10.0.2.1~10.0.2.16,其中10.0.2.10不能配置。

    for ip in {1..16}
    do
    	if [ $ip -eq 10 ];then
    		continue
    	else
    		ifconfig ens33:$ip 10.0.0.${ip}/24 up
    	fi
    done
    

    4)shell 脚本实现

    [root@zabbix 0513]# cat add_ip.sh 
    #!/bin/bash
    [ -f /etc/init.d/functions ]&& . /etc/init.d/functions
    RETVAL=0
    function operation(){
        if [ "$1" == "del" ];then
    	list=`echo {16..1}`
        else 
    	list=`echo {1..16}`
        fi
        for ip in $list
        do
    	if [ $ip -eq 10 ];then
    	    continue
    	fi
    	ip addr $1 10.0.0.${ip}/24 dev eth0 lable eth0:$ip &>/dev/null
    	RETVAL=$?
    	if [ $RETVAL -eq 0 ];then
    	    action "$1 $ip" /bin/true
    	else
    	    action "$1 $ip" /bin/false
    	fi
        done
       return $RETVAL
    }
    case "$1" in
        start)
    	operation add
    	RETVAL=$?
    	;;
        stop)
    	operation del 
            RETVAL=$?
    	;;
        restart)
    	operation del
    	sleep 2
    	operation add
    	RETVAL=$?
    	;;
        *)
    	printf $"USAGE: $0 {start|stop|restart}"
    esac
    exit $RETVAL
    
    

    12.4.2 RANDOM随机数md5比对

    范例12-4:

    已知下面的字符串是通过将RANDOM随机数采用md5sum加密后任意取出连续10位的结果,

    请破解这些字符串对应的md5sum前的数字?


    解题思路:本题原本是想考察break的用法,但是还考察了RANDOM随机数的范围,
    该范围是0~32767,请务必记住。

    要想解决本题,首先要将0~32767范围内的所有数字通过md5sum加密,
    并把加密后的字符串和加密前的数字对应地写到日志里。

    然后将题中给出的加密后的字符串4fe8bf20ed和指纹库里的所有使用md5sum加密后的字符串
    进行比对(grep最佳),如果匹配,则把对应的行及对应的数字输出。


    首先将0~32767范围内的所有数字通过md5sum加密,
    并把加密后的字符串和加密前的数字对应地写到日志里,实现脚本如下:

    [root@zabbix 0514]# cat random.sh
    #!/bin/bash
    for n in {0..327767}
    do
    	echo "`echo $n|md5sum` $n" >>/tmp/finger.txt
    done
    # [root@zabbix 0514]# grep -w 722 /tmp/finger.txt
    # f136b51b96a2a2ccefab9b82f1182d91  - 722
    md5char="f136b51b96a2a2ccefab9b82f1182d91"
    while read line
    do
        if [ `echo $line|grep "$md5char" |wc -l` -eq 1 ];then
    	echo $line
    	break
        fi
    done < /tmp/finger.txt
    [root@zabbix 0514]# sh random.sh 
    f136b51b96a2a2ccefab9b82f1182d91 - 722
    
  • 相关阅读:
    八数码(BFS)
    食物链(并查集)
    最大异或对(Trie)
    解决espeak编译的一些问题
    AcWing 3779. 相等的和
    AcWing 3775. 数组补全(环图)
    AcWing 3728. 城市通电(最小生成树)
    AcWing 3727. 乘方相乘(进位制)
    tarjan
    LC刷题简要记录
  • 原文地址:https://www.cnblogs.com/moox/p/12886517.html
Copyright © 2011-2022 走看看