【运维知识高级篇】超详细的Shell编程讲解4(for循环+并发问题+while循环+流程控制语句+函数传参+函数变量+函数返回值+反向破解MD5)(二)

简介: 【运维知识高级篇】超详细的Shell编程讲解4(for循环+并发问题+while循环+流程控制语句+函数传参+函数变量+函数返回值+反向破解MD5)(二)

流程控制语句

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年运维经验,持续分享运维干货,感谢大家的阅读和关注!

目录
相关文章
|
5天前
|
Shell Python
python 和shell 变量互相传递
python 和shell 变量互相传递
24 0
|
5天前
|
存储 运维 Shell
shell中for while until 三种循环的用法
shell编程中,有几种常见的循环结构,包括for循环、while循环和until循环,总的来说,循环shell编程中扮演着至关重要的角色,它们使得自动化任务变得更加容易,提高了效率,并且可以处理各种各样的编程需求。
257 13
shell中for while until 三种循环的用法
|
5天前
|
Shell Linux
|
5天前
|
Shell Linux Perl
Linux|如何允许 awk 使用 Shell 变量
Linux|如何允许 awk 使用 Shell 变量
14 2
|
5天前
|
存储 Shell C语言
shell脚本 编程 变量 基本入门(详解)
shell脚本 编程 变量 基本入门(详解)
|
5天前
|
监控 Shell
shell学习(五) 【循环控制continue,break、while 语法】
shell学习(五) 【循环控制continue,break、while 语法】
13 0
|
5天前
|
Shell
shell学习(三)【shell变量、数组,文件命令、特殊变量】
shell学习(三)【shell变量、数组,文件命令、特殊变量】
15 0
|
5天前
|
Shell
shell 命令(一)概述【别名、 bash重定向 、定义变量】
shell 命令(一)概述【别名、 bash重定向 、定义变量】
23 0
|
5天前
|
Shell
【shell】shell命令行放在变量中执行以及变量的常用方法
【shell】shell命令行放在变量中执行以及变量的常用方法
|
5天前
|
存储 Shell Linux
【Shell 命令集合 系统设置 内建命令】⭐Linux 声明变量的属性和类型 declare命令 使用指南
【Shell 命令集合 系统设置 内建命令】⭐Linux 声明变量的属性和类型 declare命令 使用指南
33 0