码迷,mamicode.com
首页 > 其他好文 > 详细

循环控制及状态返回值

时间:2018-10-09 17:02:15      阅读:160      评论:0      收藏:0      [点我收藏+]

标签:fan   cti   curl   tps   poj   exp   循环   sum   lse   

1.break、continue、exit、return的区别

break、continue在条件语句及循环语句(for、while、if等)中用于控制程序的走向;而exit则用于终止所有语句并退出当前脚本了,除此之外exit还可以返回上一次程序或命令的执行状态值给当前shell;ruturn和exit类似,只不过return用于在函数内部返回函数执行的状态值。基本说明如下图所示:

技术分享图片

2.break、continue、exit功能执行流程图

以while循环和for循环举例。break功能执行流程图如下图所示:

技术分享图片

continue功能执行流程图如下所示:

技术分享图片

exit功能的执行流程图如下图所示:

技术分享图片

3.break、continue、exit、return命令示例

范例:通过下面的脚本验证break、continue、exit、return命令的功能

[root@shellbiancheng jiaobenlianxi]# cat xunhuankongzhi.sh
#!/bin/bash
if [ $# -ne 1 ];then   如果参数不为执行if语句里面的echo命令
echo $"Usage:$0 {break|continue|exit|return}" 分别传入4个命令作为参数
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." 执行for循环外的输出提示
}
test $*    调用test函数,实现脚本传参
func_ret=$?    接收并测试函数的返回值
if [ `echo $*|grep return|wc -l` -eq 1 ] 如果传参是return执行难,if语句中echo命令
then
echo "return‘s exit status:$func_ret" 如果传参是return,打印函数的返回值
fi
echo "ok"             函数体外的输出提示

(1)验证break命令,执行结果如下

[root@shellbiancheng jiaobenlianxi]# sh xunhuankongzhi.sh 
Usage:xunhuankongzhi.sh {break|continue|exit|return}
[root@shellbiancheng jiaobenlianxi]# sh xunhuankongzhi.sh break
0
1
2
I am in func.
ok

从结果可以看出,当i=3时执行了break命令循环中以后的命令没有执行,但是循环外的echo命令执行了,执行到break时跳出了if以及for循环,然后执行test函数中的echo命令以及test函数体外的echo命令。

(2)验证continue命令,执行结果如下

[root@shellbiancheng jiaobenlianxi]# sh xunhuankongzhi.sh continue
0
1
2
4
5
I am in func.
ok

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

(3)验证exit命令,在下一个shell里可以用“$?”接收exit n的返回值,执行结果如下:

[root@shellbiancheng jiaobenlianxi]# sh xunhuankongzhi.sh "exit 100"
0
1
2
[root@shellbiancheng jiaobenlianxi]# echo $?
100

从结果可以看出,当进入循环里的if语句后遇到“exit 100”时,立刻腿出程序;不但循环体3后面的数字没有输出,而且for循环体done外的echo和函数外的ok也没有输出,就直接退出了程序。另外因为程序退出时指定100,所以执行脚本后用“$?”获取返回值就返回了100。

(4)验证return命令,执行结果如下

[root@shellbiancheng jiaobenlianxi]# sh xunhuankongzhi.sh "return 100"
0
1
2
return‘s exit status:100
ok
[root@shellbiancheng jiaobenlianxi]# echo $?
0

当执行到return 100时,就没有执行3一下的数字,说明return跳出了循环体、for循环体done后echo也没有执行而是直接执行后函数体外面的内容,可以看出return的作用是退出当前函数。同return将数字100作为函数的返回值返回给函数体外,返回值$func_ret的值等于100。执行脚本后打印的返回值是0,因为程序左后打印的是echo命令,执行成功,多以执行脚本最后返回值是0。

4.案例

(1)案例1:开发shell脚本实现为服务器临时配置多个IP,并且不能临时撤销配置的所有IP,IP地址范围为:192.168.136.220-192.168.136.225,其中192.168.136.223不能设置。

使用ifconfig给IP设置别名:

ifconfig eth0:0 192.168.136.224/24 up  添加别名
ifconfig eth0:0 192.168.136.224/24 down  删除别名

使用ip addr给IP设置别名:

ip addr add 192.168.136.224/24 dev eth0 label eth0:0  添加别名
ip addr del 192.168.136.224/24 dev eth0 label eth0:0  删除别名

代码如下:

[root@shellbiancheng jiaobenlianxi]# cat ipalias.sh  
#!/bin/bash
[ -f "/etc/init.d/functions" ] && . /etc/init.d/functions
RETVAL=0
export PATH="/usr/local/mysql/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/curl/bin:/root/bin"

function add(){

for ip in {220..225}
do
if [ $ip -eq 223 ];then
continue
fi
ip addr add 192.168.136.$ip/24 dev eth0 label eth0:$ip &>/dev/null
RETVAL=$?
if [ $RETVAL -eq 0 ];then
action "add $ip" /bin/true
else
action "add $ip" /bin/false
fi
done
return $RETVAL
}

function del(){
for ip in {225..220}
do  
if [ $ip -eq 223 ];then
continue 
fi
ip addr del 192.168.136.$ip/24 dev eth0 label eth0:$ip &>/dev/null
RETVAL=$?
if [ $RETVAL -eq 0 ];then
action "del $ip" /bin/true
else
action "del $ip" /bin/false
fi
done
return $RETVAL

}

function main(){

case "$1" in
start)
  add
  RETVAL=$?
  ;;
 stop)
 del
 RETVAL=$?
 ;;
  restart)
 del
 sleep 2
 add
 RETVAL=$?  
 ;;
*)
 printf "Usage:$0 {start|stop|restart}\n"
esac

}

main $1
exit $RETVAL

(2)案例2:分析apache访问日志,把日志中每行的访问字节数对应的字段数相加,计算出访问量。用while循环实现。朋友们做测试的时候如果没有访问日志可以去网上下载一个访问日志。

[root@shellbiancheng jiaobenlianxi]# cat apachefangwen.sh 
#!/bin/bash
sum=0
RETVAL=0
byte="1024"
b="/home/linzhongniao/tools/access_2013_05_30.log"
exec <$b
while read line 
do
   size=`echo  $line|awk ‘{print $10}‘|grep -v "-"|tr ‘\r‘ ‘ ‘`  
   expr $size + 1 &>/dev/null
   if [ $? -ne $RETVAL ];then
continue
   fi
   ((sum+=size))
done
echo "${b}:total:${sum}bytes = `expr ${sum} / $byte`KB"

(3)案例3:破解用RANDOM生成的随机数“0~32767”范围内的所有数字用md5sum加密之前的数字?

解决过程,先将0-32767范围内的所有数字通过md5sum加密,并把加密后的字符串和加密前的数字对应的写入到日志文件中,脚本如下:

[root@shellbiancheng jiaobenlianxi]# cat RANDOM.sh 
#!/bin/bash
for n in {0..32767}
do
echo "`echo $n|md5sum` $n" >>/tmp/zhiwen1.log

done

查看执行结果:

[root@shellbiancheng jiaobenlianxi]# head /tmp/zhiwen.log 
897316929176464ebc9ad085f31e7284  - 0
b026324c6904b2a9cb4b88d6d61c81d1  - 1
26ab0db90d72e28ad0ba1e22ee510510  - 2
6d7fce9fee471194aa8b5b6e47267f03  - 3
48a24b70a0b376535542b996af517398  - 4
1dcca23355272056f04fe8bf20edfce0  - 5
9ae0ea9e3c9c6e1b9b6252c8395efdc1  - 6
84bc3da1b3e33a18e8d5e1bdd7a18d7a  - 7
c30f7472766d25af1dc80b3ffc9a58c7  - 8
7c5aba41f53293b712fd86d08ed5b36e  - 9

解密加密后的字符串3ae5dc2d,和指纹库里面的所有使用md5sum加密后的字符串进行比对,如果匹配输出加密之前的数字。

[root@shellbiancheng jiaobenlianxi]# cat md5pojie.sh   
#!/bin/bash
#for n in {0..32767}
#do

#   echo "`echo $n|md5sum` $n" >>/tmp/zhiwen.log
#done

exec </tmp/zhiwen.log
md5char="3ae5dc2d"
while read line
do
  if [ `echo "$line"|grep "$md5char"|wc -l` -eq 1 ];then
  echo "$line"
  break
  fi

done

执行结果:3ae5dc2d加密之前的数字为10000

[root@shellbiancheng jiaobenlianxi]# sh md5pojie.sh 
154773ae5dc2d36d8b9747e5d3dbfc36  - 10000

循环控制及状态返回值

标签:fan   cti   curl   tps   poj   exp   循环   sum   lse   

原文地址:http://blog.51cto.com/10642812/2296197

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!