流程控制语句
exit,break,continue
exit 退出脚本
break 跳出循环
continue 忽略当前剩余代码,从头继续执行
一、exit
1. [root@LB00 Day04]# cat liucheng.sh 2. #!/bin/bash 3. while true 4. do 5. echo 1 6. exit 7. echo 2 8. done 9. echo 3 10. [root@LB00 Day04]# sh liucheng.sh 11. 1
二、break
1. [root@LB00 Day04]# cat liucheng.sh 2. #!/bin/bash 3. while true 4. do 5. echo 1 6. break 7. echo 2 8. done 9. echo 3 10. [root@LB00 Day04]# sh liucheng.sh 11. 1 12. 3
三、continue
1. [root@LB00 Day04]# cat liucheng.sh 2. #!/bin/bash 3. while true 4. do 5. echo 1 6. continue 7. echo 2 8. done 9. echo 3 10. [root@LB00 Day04]# sh liucheng.sh 11. 1 12. 1 13. 1 14. ...... 15. 16. #continu使用示例 17. [root@LB00 Day04]# cat liucheng.sh 18. #!/bin/bash 19. while true 20. do 21. read -p "请输入密码: " pass 22. if ! [ $pass == 123456 ];then 23. echo "密码输入错误" 24. continue 25. else 26. echo "密码输入正确" 27. break; 28. fi 29. done 30. echo "登录成功" 31. [root@LB00 Day04]# sh liucheng.sh 32. 请输入密码: 1 33. 密码输入错误 34. 请输入密码: 123456 35. 密码输入正确 36. 登录成功
函数
1、完成特定功能的代码块
2、可以复用
3、函数类似变量,先定义再调用,区别是变量不调用也会执行,但是函数不调用不执行
一、函数定义
1. [root@LB00 Day04]# cat fun.sh 2. #!/bin/bash 3. fun1(){ 4. echo "第一种函数定义方法" 5. } 6. function fun2 { #注意不加括号有空格 7. echo "第二种函数定义方法" 8. } 9. function fun3(){ 10. echo "第三种函数定义方法" 11. } 12. fun1 13. fun2 14. fun3 15. [root@LB00 Day04]# sh fun.sh 16. 第一种函数定义方法 17. 第二种函数定义方法 18. 第三种函数定义方法
与变量不同,函数不调用不执行,变量不调用也执行
1. [root@LB00 Day04]# cat fun.sh 2. #!/bin/bash 3. name=koten 4. fun1(){ 5. echo "第一种函数定义方法" 6. } 7. function fun2 { 8. echo "第二种函数定义方法" 9. } 10. function fun3(){ 11. echo "第三种函数定义方法" 12. } 13. [root@LB00 Day04]# sh -x fun.sh 14. + name=koten
想在当前shell执行,直接source脚本或者. 脚本即可,跟变量同理
1. [root@LB00 Day04]# source fun.sh 2. [root@LB00 Day04]# echo $name 3. koten 4. [root@LB00 Day04]# fun1 5. 第一种函数定义方法
二、函数传参
与脚本传参不同,函数中不能直接接受shell的传参
错误方式
1. [root@LB00 Day04]# cat chuancan.sh 2. #!/bin/bash 3. fun1(){ 4. if [ -f $1 ];then 5. echo 文件存在 6. else 7. echo 文件不存在 8. fi 9. } 10. fun1 11. [root@LB00 Day04]# sh chuancan.sh /etc/passwd #虽然显示存在 12. 文件存在 13. [root@LB00 Day04]# sh -x chuancan.sh /etc/passwd #但是看流程,函数中并没有显示 14. + fun1 15. + '[' -f ']' 16. + echo 文件存在 17. 文件存在
正确用法,直接写到调用名称后面
1. [root@LB00 Day04]# cat chuancan.sh 2. #!/bin/bash 3. fun1(){ 4. if [ -f $1 ];then 5. echo 文件存在 6. else 7. echo 文件不存在 8. fi 9. } 10. fun1 $1 11. [root@LB00 Day04]# sh chuancan.sh /etc/passwd 12. 文件存在
注意区分脚本中的参数与函数中的参数
1. [root@LB00 Day04]# cat chuancan.sh 2. #!/bin/bash 3. fun1(){ 4. if [ -f $1 ];then #这个是调用函数的传参 5. echo $1 文件存在 6. else 7. echo $1 文件不存在 8. fi 9. } 10. fun1 $2 $1 #这个是执行脚本时候的传参 11. [root@LB00 Day04]# sh chuancan.sh /etc/hosts /etc/passwd 12. /etc/passwd 文件存在
也可以通过变量的方式传参,一开始定义好变量
1. [root@LB00 Day04]# cat chuancan.sh 2. #!/bin/bash 3. file=$1 4. fun1(){ 5. if [ -f $file ];then 6. echo $file 文件存在 7. else 8. echo $file 文件不存在 9. fi 10. } 11. fun1 12. [root@LB00 Day04]# sh chuancan.sh /etc/passwd 13. /etc/passwd 文件存在
三、函数变量
函数中可以调用shell脚本的变量
在函数中定义的变量可以只在函数体中生效,在shell中不生效
1. #正常是在函数体内外都会生效 2. [root@LB00 Day04]# cat bianliang.sh 3. #!/bin/bash 4. fun1(){ 5. name=koten 6. echo $name 7. } 8. fun1 9. echo $name 10. [root@LB00 Day04]# sh bianliang.sh 11. koten 12. koten 13. 14. #只在函数体中生效 15. [root@LB00 Day04]# cat bianliang.sh 16. #!/bin/bash 17. fun1(){ 18. local name=koten 19. echo $name 20. } 21. fun1 22. echo $name 23. [root@LB00 Day04]# sh bianliang.sh 24. koten 25. 26. [root@LB00 Day04]#
四、函数返回值
exit和return都可以定义
1. [root@LB00 Day04]# cat fanhuizhi.sh 2. #!/bin/bash 3. if [ -f $1 ];then 4. echo "$1 存在" 5. exit 100 6. else 7. echo "$1 不存在" 8. exit 50 9. fi 10. [root@LB00 Day04]# sh fanhuizhi.sh /etc/passwd 11. /etc/passwd 存在 12. [root@LB00 Day04]# echo $? 13. 100 14. 15. [root@LB00 Day04]# cat fanhuizhi.sh 16. #!/bin/bash 17. fun1(){ 18. if [ -f $1 ];then 19. echo "存在" 20. return 100 21. else 22. echo "不存在" 23. return 99 24. fi 25. } 26. fun1 $? 27. echo $? 28. [root@LB00 Day04]# sh fanhuizhi.sh /etc/passwd 29. 不存在 30. 99
使用返回值的时候容易出错,我们要时刻注意返回值是否有因为执行了新的命令而刷新
如下所示的错误写法!
1. [root@LB00 Day04]# cat fanhuizhi.sh 2. #!/bin/bash 3. fun1(){ 4. if [ -f $1 ];then 5. return 100 6. else 7. return 50 8. fi 9. } 10. fun1 $1 11. [ $? -eq 50 ] && echo 文件不存在 12. [ $? -eq 100 ] && echo 文件存在 13. [root@LB00 Day04]# sh fanhuizhi.sh /etc/passwdd 14. 文件不存在 15. [root@LB00 Day04]# sh fanhuizhi.sh /etc/passwd 16. [root@LB00 Day04]#
由于在执行完函数后又执行了$?与50的判断,所以判断后$?刷新成了其他数值,所以永远不会echo出文件存在,这种情况一般有两种解决办法。
1. [root@LB00 Day04]# cat fanhuizhi.sh 2. #!/bin/bash 3. fun1(){ 4. if [ -f $1 ];then 5. return 100 6. else 7. return 50 8. fi 9. } 10. fun1 $1 11. [ $? -eq 50 ] && echo 文件不存在 12. echo $? 13. [ $? -eq 100 ] && echo 文件存在 14. [root@LB00 Day04]# sh fanhuizhi.sh /etc/passwd 15. 1
一种是将两个条件表达式写成一个,在使用函数的返回值之前不执行其他命令。
1. [root@LB00 Day04]# cat fanhuizhi.sh 2. #!/bin/bash 3. fun1(){ 4. if [ -f $1 ];then 5. return 100 6. else 7. return 50 8. fi 9. } 10. fun1 $1 11. [ $? -eq 50 ] && echo 文件不存在 || echo 文件存在 12. [root@LB00 Day04]# sh fanhuizhi.sh /etc/passwd 13. 文件存在 14. [root@LB00 Day04]# sh fanhuizhi.sh /etc/passwdddd 15. 文件不存在
另一种也是系统中常做的操作,就是当我们的函数体执行完毕后给一个变量,后面用变量去判断,这样$?有变化也没有关系,反正变量不会有变化。
1. [root@LB00 Day04]# cat fanhuizhi.sh 2. #!/bin/bash 3. fun1(){ 4. [ -f $1 ];then 5. return 100 6. else 7. return 50 8. fi 9. } 10. fun1 $1 11. re=$? 12. [ $re -eq 50 ] && echo 文件不存在 13. [ $re -eq 100 ] && echo 文件存在 14. [root@LB00 Day04]# sh fanhuizhi.sh /etc/passwd 15. 文件存在 16. [root@LB00 Day04]# sh fanhuizhi.sh /etc/passwdddd 17. 文件不存在
扩展:反向破解MD5
下面是随机数的md5值,4个取了前8位,2两个取了前7位,通过脚本反向破解出随机数
1. echo $((RANDOM))|md5sum|cut -c1-8 2. 0b364f36 3. 7f1e6feb 4. c5b795e2 5. 5f8b9f68 6. echo $((RANDOM))|md5sum|cut -c1-7 7. 081691c 8. 76728eb
我们的思路就是利用for循环反向破解,优化就是尽可能少的操作,加快遍历速度,更快的破解出来
1. [root@LB00 Day04]# cat fanxiang.sh 2. #!/bin/bash 3. for i in `seq 32767` 4. do 5. md5=`echo $i|md5sum` 6. md5_7=`echo $md5|cut -c1-7` 7. md5_8=`echo $md5|cut -c1-8` 8. if [ "$md5_7" == 081691c ];then 9. echo $i $md5_7 10. elif [ "$md5_7" == 76728eb ];then 11. echo $i $md5_7 12. elif [ "$md5_8" == 0b364f36 ];then 13. echo $i $md5_8 14. elif [ "$md5_8" == 7f1e6feb ];then 15. echo $i $md5_8 16. elif [ "$md5_8" == c5b795e2 ];then 17. echo $i $md5_8 18. elif [ "$md5_8" == 5f8b9f68 ];then 19. echo $i $md5_8 20. fi 21. done 22. [root@LB00 Day04]# sh fanxiang.sh 23. 691 c5b795e2 24. 5343 081691c 25. 11902 7f1e6feb 26. 21364 76728eb 27. 25375 5f8b9f68 28. 30458 0b364f36
我是koten,10年运维经验,持续分享运维干货,感谢大家的阅读和关注!