【运维知识高级篇】超详细的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年运维经验,持续分享运维干货,感谢大家的阅读和关注!

目录
相关文章
|
3月前
|
Unix Shell Linux
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
本文提供了几个Linux shell脚本编程问题的解决方案,包括转置文件内容、统计词频、验证有效电话号码和提取文件的第十行,每个问题都给出了至少一种实现方法。
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
|
3月前
|
Shell Linux
Linux shell编程学习笔记30:打造彩色的选项菜单
Linux shell编程学习笔记30:打造彩色的选项菜单
|
1月前
|
运维 监控 Shell
深入理解Linux系统下的Shell脚本编程
【10月更文挑战第24天】本文将深入浅出地介绍Linux系统中Shell脚本的基础知识和实用技巧,帮助读者从零开始学习编写Shell脚本。通过本文的学习,你将能够掌握Shell脚本的基本语法、变量使用、流程控制以及函数定义等核心概念,并学会如何将这些知识应用于实际问题解决中。文章还将展示几个实用的Shell脚本例子,以加深对知识点的理解和应用。无论你是运维人员还是软件开发者,这篇文章都将为你提供强大的Linux自动化工具。
|
2月前
|
Shell
Shell编程(下)
Shell编程(下)
111 1
|
2月前
|
Shell Linux Windows
Shell编程(上)
Shell编程(上)
47 1
|
2月前
|
Shell Linux 开发工具
|
2月前
|
监控 Unix Shell
shell脚本编程学习
【10月更文挑战第1天】shell脚本编程
83 12
|
2月前
|
存储 运维 监控
自动化运维:使用Shell脚本简化日常任务
【9月更文挑战第35天】在IT运维的日常工作中,重复性的任务往往消耗大量的时间。本文将介绍如何通过编写简单的Shell脚本来自动化这些日常任务,从而提升效率。我们将一起探索Shell脚本的基础语法,并通过实际案例展示如何应用这些知识来创建有用的自动化工具。无论你是新手还是有一定经验的运维人员,这篇文章都会为你提供新的视角和技巧,让你的工作更加轻松。
77 2
|
3月前
|
Shell Linux
Linux shell编程学习笔记82:w命令——一览无余
Linux shell编程学习笔记82:w命令——一览无余
|
3月前
|
存储 Unix Shell
shell脚本编程基础
【9月更文挑战第4天】
54 12